├── .gitignore ├── LICENSE ├── Page.js ├── README.md ├── package-lock.json ├── package.json ├── pages ├── _app.js ├── index.js ├── isr.js ├── ssg.js └── ssr.js ├── public ├── favicon.ico └── vercel.svg ├── publicApis.js └── styles ├── Home.module.css └── globals.css /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ido Shamun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Page.js: -------------------------------------------------------------------------------- 1 | import { useRouter } from 'next/router'; 2 | 3 | export default function Page(props) { 4 | const { isFallback } = useRouter(); 5 | 6 | if (isFallback) { 7 | return <>; 8 | } 9 | 10 | return
11 |

{props.name}

12 |

{props.description}

13 |
14 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. 16 | 17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. 18 | 19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-isr-logrocket", 3 | "scripts": { 4 | "dev": "next dev", 5 | "build": "next build", 6 | "start": "next start" 7 | }, 8 | "dependencies": { 9 | "next": "10.0.4", 10 | "node-fetch": "^2.6.1", 11 | "react": "17.0.1", 12 | "react-dom": "17.0.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | 3 | function MyApp({ Component, pageProps }) { 4 | return 5 | } 6 | 7 | export default MyApp 8 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import Head from 'next/head' 2 | import Link from 'next/link' 3 | import styles from '../styles/Home.module.css' 4 | 5 | export default function Home() { 6 | return ( 7 |
8 | 9 | Next.js ISR Demo 10 | 11 | 12 | 13 |
14 |

15 | Welcome to my demo! 16 |

17 | 18 |
19 | 20 | 21 |

ISR →

22 |

Fetches a random public API every revalidation period

23 |
24 | 25 | 26 | 27 | 28 |

SSG →

29 |

Fetches a random public API at build time

30 |
31 | 32 | 33 | 34 | 35 |

SSR →

36 |

Fetches a random public API on every request

37 |
38 | 39 |
40 |
41 |
42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /pages/isr.js: -------------------------------------------------------------------------------- 1 | import Page from '../Page'; 2 | import { getRandomAPI } from '../publicApis'; 3 | 4 | export default Page; 5 | 6 | export async function getStaticProps() { 7 | const props = await getRandomAPI(); 8 | return { props, revalidate: 30 }; 9 | } -------------------------------------------------------------------------------- /pages/ssg.js: -------------------------------------------------------------------------------- 1 | import Page from '../Page'; 2 | import { getRandomAPI } from '../publicApis'; 3 | 4 | export default Page; 5 | 6 | export async function getStaticProps() { 7 | const props = await getRandomAPI(); 8 | return { props }; 9 | } -------------------------------------------------------------------------------- /pages/ssr.js: -------------------------------------------------------------------------------- 1 | import Page from '../Page'; 2 | import { getRandomAPI } from '../publicApis'; 3 | 4 | export default Page; 5 | 6 | export async function getServerSideProps() { 7 | const props = await getRandomAPI(); 8 | return { props }; 9 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idoshamun/nextjs-isr-logrocket/b0bc83a285a62abe39047346b9e5fdf8bbd40fce/public/favicon.ico -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /publicApis.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | 3 | export async function getRandomAPI() { 4 | const res = await fetch('https://api.publicapis.org/random'); 5 | const json = await res.json(); 6 | return { 7 | name: json.entries[0].API, 8 | description: json.entries[0].Description, 9 | }; 10 | } -------------------------------------------------------------------------------- /styles/Home.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | min-height: 100vh; 3 | padding: 0 0.5rem; 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: center; 7 | align-items: center; 8 | } 9 | 10 | .main { 11 | padding: 5rem 0; 12 | flex: 1; 13 | display: flex; 14 | flex-direction: column; 15 | justify-content: center; 16 | align-items: center; 17 | } 18 | 19 | .title { 20 | margin: 0; 21 | line-height: 1.15; 22 | font-size: 4rem; 23 | } 24 | 25 | .title, 26 | .description { 27 | text-align: center; 28 | } 29 | 30 | .description { 31 | line-height: 1.5; 32 | font-size: 1.5rem; 33 | } 34 | 35 | .grid { 36 | display: flex; 37 | align-items: center; 38 | justify-content: center; 39 | flex-wrap: wrap; 40 | max-width: 800px; 41 | margin-top: 3rem; 42 | } 43 | 44 | .card { 45 | margin: 1rem; 46 | flex-basis: 45%; 47 | padding: 1.5rem; 48 | text-align: left; 49 | color: inherit; 50 | text-decoration: none; 51 | border: 1px solid #eaeaea; 52 | border-radius: 10px; 53 | transition: color 0.15s ease, border-color 0.15s ease; 54 | } 55 | 56 | .card:hover, 57 | .card:focus, 58 | .card:active { 59 | color: #0070f3; 60 | border-color: #0070f3; 61 | } 62 | 63 | .card h3 { 64 | margin: 0 0 1rem 0; 65 | font-size: 1.5rem; 66 | } 67 | 68 | .card p { 69 | margin: 0; 70 | font-size: 1.25rem; 71 | line-height: 1.5; 72 | } 73 | 74 | @media (max-width: 600px) { 75 | .grid { 76 | width: 100%; 77 | flex-direction: column; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | } 8 | 9 | a { 10 | color: inherit; 11 | text-decoration: none; 12 | } 13 | 14 | * { 15 | box-sizing: border-box; 16 | } 17 | --------------------------------------------------------------------------------