Skip to content
Dashboard

Next.js: Server-side Rendering vs. Static Generation

VP of Developer Experience

Link to headingE-commerce Next.js App Example

Link to headingPer-page Basis

Link to headingAbout Us Page: Static Generation without Data

pages/about.js
// This page can can be pre-rendered without
// external data: It will be pre-rendered
// into a HTML file at build time.
export default function About() {
return (
<div>
<h1>About Us</h1>
{/* ... */}
</div>
)
}

Link to headingAll Products Page: Static Generation with Data

// This function runs at build time on the build server
export async function getStaticProps() {
return {
props: {
products: await getProductsFromDatabase()
}
}
}
// The page component receives products prop
// from getStaticProps at build time
export default function Products({ products }) {
return (
<>
<h1>Products</h1> 
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
</>
)
}

Link to headingIndividual Product Page: Static Generation with Data

pages/products/[id].js
// In getStaticPaths(), you need to return the list of
// ids of product pages (/products/[id]) that you’d
// like to pre-render at build time. To do so,
// you can fetch all products from a database.
export async function getStaticPaths() {
const products = await getProductsFromDatabase()
const paths = products.map((product) => ({
params: { id: product.id }
}))
// fallback: false means pages that don’t have the
// correct id will 404.
return { paths, fallback: false }
}
// params will contain the id for each generated page.
export async function getStaticProps({ params }) {
return {
props: {
product: await getProductFromDatabase(params.id)
}
}
}
export default function Product({ product }) {
// Render product
}

Link to headingIncremental Static Generation

Link to headingAdding Pages (Fallback)

pages/products/[id].js
export async function getStaticProps({ params }) {
// ...
}
export async function getStaticPaths() {
// ...
// fallback: true means that the missing pages
// will not 404, and instead can render a fallback.
return { paths, fallback: true }
}
export default function Product({ product }) {
const router = useRouter()
if (router.isFallback) {
return <div>Loading...</div>
}
// Render product...
}

Link to headingUpdating Existing Pages (Incremental Static "Re"generation)

pages/products/[id].js
export async function getStaticProps({ params }) {
return {
props: {
product: await getProductFromDatabase(params.id)
},
revalidate: 60
}
}

Link to headingShopping Cart Page: Static Generation without Data, Combined with Client-side Fetching

import useSWR from 'swr'
function ShoppingCart() {
// fetchAPI is the function to do data fetching
const { data, error } = useSWR('/api/cart', fetchAPI)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>Items in Cart: {data.products.length}</div>
}

Link to headingBenefits of Static

Link to headingServer-side Rendering

Link to headingAlso: Writing Data

export default async (req, res) => {
const response = await fetch(`https://.../cart`, {
body: JSON.stringify({
productId: req.query.productId
}),
headers: {
Authorization: `Token ${process.env.YOUR_API_KEY}`,
'Content-Type': 'application/json'
},
method: 'POST'
})
const { products } = await response.json()
return res.status(200).json({ products })
};

Link to headingConclusion

Ready to deploy?