All the Ways to Render Pages in Next.js (With Simple Examples)
Next.js offers multiple ways to render pages, each with different use cases. Let’s go through them one by one with simple examples.
1. Static Site Generation (SSG)
Best for: Pages that don’t change often (e.g., blog posts, documentation).
SSG generates the page at build time, meaning the page is pre-built as an HTML file and served quickly.
Example:
export async function getStaticProps() {
const data = await fetch('https://api.example.com/data').then(res => res.json());
return {
props: { data },
};
}
export default function Page({ data }) {
return <div>Data: {data.message}</div>;
}How it works:
getStaticPropsruns at build time.- The page is pre-rendered and served as static HTML.
2. Incremental Static Regeneration (ISR)
Best for: Updating static pages without rebuilding the whole site.
ISR allows pages to be updated after deployment at a specified interval.
Example:
export async function getStaticProps() {
const data = await fetch('https://api.example.com/data').then(res => res.json());
return {
props: { data },
revalidate: 10, // Regenerates the page every 10 seconds
};
}
export default function Page({ data }) {
return <div>Data: {data.message}</div>;
}How it works:
- The page is cached and served as static HTML.
- After 10 seconds, a new version is generated.
3. Server-Side Rendering (SSR)
Best for: Pages that need fresh data on every request (e.g., dashboards).
SSR generates the page on every request at runtime.
Example:
export async function getServerSideProps() {
const data = await fetch('https://api.example.com/data').then(res => res.json());
return {
props: { data },
};
}
export default function Page({ data }) {
return <div>Data: {data.message}</div>;
}How it works:
getServerSidePropsruns on each request.- The page is dynamically generated before sending the response.
4. Client-Side Rendering (CSR)
Best for: Pages that need fast loading and fetch data after the page loads.
CSR loads the page first and fetches data in the browser.
Example:
import { useEffect, useState } from 'react';
export default function Page() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(res => res.json())
.then(setData);
}, []);
return <div>Data: {data ? data.message : 'Loading...'}</div>;
}How it works:
- The page loads immediately.
- Data is fetched after the initial render.
5. Hybrid Rendering
Best for: Combining multiple rendering methods in a single page.
You can mix SSR, SSG, ISR, and CSR depending on the data source.
Example:
import { useEffect, useState } from 'react';
export async function getServerSideProps() {
const initialData = await fetch('https://api.example.com/data').then(res => res.json());
return { props: { initialData } };
}
export default function Page({ initialData }) {
const [data, setData] = useState(initialData);
useEffect(() => {
fetch('https://api.example.com/data')
.then(res => res.json())
.then(setData);
}, []);
return <div>Data: {data.message}</div>;
}How it works:
getServerSidePropsprovides initial data.useEffectfetches updated data after the page loads.
Conclusion
| Rendering Method | When to Use? | Example |
|---|---|---|
| SSG (Static) | Content rarely changes | Blog posts |
| ISR (Static + Updates) | Content changes occasionally | News pages |
| SSR (Dynamic) | Content changes on every request | Dashboards |
| CSR (Client-side) | Fast initial load, data fetch after | User feeds |
| Hybrid | Mix of methods | Personal dashboards |