SSG, SSR, ISR
Nextjs gives you options (ssg, ssr, isr) on a page by page basis for generating pages.
SSG - Static site generation
GetStaticProps
Specifically when using frameworks like Next.js—”Static Props” refers to a method of fetching data at build time. Static props is pre-rendered html for use in static html. You can use get Static props for content that does not change. Sales pages, blog posts. documentation. This is the SSG “Static site Generator” approach to building pages.
The “Static” Part
The term “Static” is used because the data (the Props) becomes part of a static file. Once the build is finished, those props are effectively “frozen” in time until the next build occurs.
Why do we call them “Props”?
In React, Props (short for properties) are the arguments you pass into a component to tell it what to display.
- Normal React: Props are passed from a parent component to a child component.
- Static Props: The Next.js Build Process acts as the “parent” and passes the data into your page component as props.
The “Hand-off”
It is helpful to visualize the hand-off between the server and the browser:
- At Build Time: The server runs your getStaticProps function, gets a JSON object of your data, and injects it into the component.
- On the User’s Screen: The user receives the HTML, but they also receive a small hidden JSON file containing those same props.
- Hydration: React “wakes up” on the client side, reads that JSON, and ensures the interactive parts of the page match the static HTML they just saw.
1
2
3
4
5
6
7
8
9
10
11
12
export async function getStaticProps() {
const data = await fetch('https://api.example.com/products');
const products = await data.json();
return {
props: { products }, // This is passed to the component
};
}
function ProductPage({ products }) {
return <div>{/* Render your products here */}</div>;
}
GetStaticPaths and getStaticParams
getStaticPaths is the function that tells Next.js exactly which dynamic pages to pre-render at build time. You use getStaticPaths to provide a list of all the IDs or slugs so the server can build the HTML files for them before anyone even visits the site.
When you use a dynamic route (like /posts/[id].js), Next.js needs to know what [id] can be.
- getStaticPaths fetches the data (e.g., a list of IDs from your database)
- It returns an object containing an array of paths
- Next.js then calls ‘getStaticProps’ for each path in that array to fetch the specific data for that page.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// pages/posts/[id].js
export async function getStaticPaths() {
// 1. Fetch data from an API or Database
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
// 2. Map the data to the required format
const paths = posts.map((post) => ({
params: { id: post.id.toString() },
}));
// 3. Return the paths and fallback behavior
return { paths, fallback: false };
}
export async function getStaticProps({ params }) {
// Fetch data for a single post using params.id
const res = await fetch(`https://api.example.com/posts/${params.id}`);
const post = await res.json();
return { props: { post } };
}
Fallback Key Comparison
| Value | Behavior | User Experience |
|---|---|---|
false | Any path not returned by getStaticPaths will result in a 404. | The user immediately sees your “Page Not Found” screen. |
true | The page is generated on-demand in the background. | The user sees a “Loading…” or skeleton state while the HTML is generated. |
'blocking' | The server generates the page on the fly (SSR style) and then caches it. | The browser “hangs” for a moment, then the user sees the full page at once. |
Pro-Tip: If you are using the newer App Router (the app/ directory), getStaticPaths has been replaced by a function called generateStaticParams. It does roughly the same thing but with a cleaner syntax!
generateStaticParams
In the App Router (the app/ directory), getStaticPaths has been replaced by generateStaticParams. It serves the same purpose but is much more intuitive because it returns a simple array of objects and works seamlessly with Server Components.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// app/posts/[id]/page.js
// 1. Define the function to generate the routes
export async function generateStaticParams() {
const posts = await fetch('https://api.example.com/posts').then((res) => res.json());
// Return a simple array of objects
return posts.map((post) => ({
id: post.id.toString(),
}));
}
// 2. The Page component receives the 'params' directly
export default async function Page({ params }) {
const { id } = params;
const post = await fetch(`https://api.example.com/posts/${id}`).then((res) => res.json());
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
);
}
Key Differences from the Pages Router
| Feature | getStaticPaths (Old) | generateStaticParams (New) |
|---|---|---|
| Data Format | Must return { params: { id: '1' } } | Returns { id: '1' } directly |
| Fallback | Controlled by fallback: true/false/blocking | Controlled by export const dynamicParams = true/false |
| Efficiency | Often required manual memoization | Automatically “dedupes” fetch requests across functions |