Data Fetching in Next.js
Data Fetching in Next.js
Next.js provides several methods for fetching data in your applications. Understanding these methods and when to use each one is crucial for building performant applications.
Server-Side Rendering (SSR)
Server-side rendering generates HTML for each request at runtime. This is useful for pages that need to show frequently updated data or personalized content.
// pages/ssr-example.js
export async function getServerSideProps(context) {
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return {
props: { data }, // Will be passed to the page component as props
}
}
export default function Page({ data }) {
return <div>Server-side rendered data: {data.title}</div>
}
Static Site Generation (SSG)
Static site generation pre-renders pages at build time. This is ideal for pages that can be built once and served by CDN, like blog posts or product pages.
// pages/ssg-example.js
export async function getStaticProps() {
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return {
props: { data },
// Re-generate at most once per 10 seconds
revalidate: 10, // In seconds
}
}
export default function Page({ data }) {
return <div>Static site generated data: {data.title}</div>
}
Incremental Static Regeneration (ISR)
ISR allows you to update static pages after they've been built without needing to rebuild the entire site. This is perfect for sites with many pages that need to stay relatively fresh.
// pages/isr-example.js
export async function getStaticProps() {
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return {
props: { data },
// Re-generate at most once per 60 seconds
revalidate: 60, // In seconds
}
}
export async function getStaticPaths() {
return {
paths: [
{ params: { id: '1' } },
{ params: { id: '2' } },
],
fallback: 'blocking', // See below for more info
}
}
export default function Page({ data }) {
return <div>ISR data: {data.title}</div>
}
Client-Side Fetching
For data that doesn't need to be pre-rendered, you can fetch it on the client side using SWR or React Query.
// pages/client-side-example.js
import { useState, useEffect } from 'react'
export default function Page() {
const [data, setData] = useState(null)
const [isLoading, setLoading] = useState(true)
useEffect(() => {
fetch('https://api.example.com/data')
.then((res) => res.json())
.then((data) => {
setData(data)
setLoading(false)
})
}, [])
if (isLoading) return <p>Loading...</p>
if (!data) return <p>No data</p>
return <div>Client-side data: {data.title}</div>
}
Using SWR for Client-Side Data Fetching
SWR is a React Hooks library for data fetching created by the Next.js team. It handles caching, revalidation, focus tracking, refetching on interval, and more.
// pages/swr-example.js
import useSWR from 'swr'
const fetcher = (...args) => fetch(...args).then(res => res.json())
export default function Page() {
const { data, error, isLoading } = useSWR(
'https://api.example.com/data',
fetcher
)
if (error) return <div>Failed to load</div>
if (isLoading) return <div>Loading...</div>
return <div>SWR data: {data.title}</div>
}
Next.js App Router and React Server Components
With Next.js 13+ and the App Router, you can use React Server Components to fetch data directly in your components without client-side JavaScript.
// app/server-component-example/page.js
async function getData() {
const res = await fetch('https://api.example.com/data')
if (!res.ok) {
throw new Error('Failed to fetch data')
}
return res.json()
}
export default async function Page() {
const data = await getData()
return <div>Server Component data: {data.title}</div>
}
Choosing the Right Data Fetching Method
Here's a quick guide to help you choose the right method:
- SSG: Use for static content that doesn't change often (blog posts, documentation)
- ISR: Use for content that changes occasionally but doesn't need real-time updates (product listings, news articles)
- SSR: Use for personalized or frequently changing content that needs SEO (user dashboards, search results)
- Client-side: Use for private, user-specific data or frequently updating content that doesn't need SEO (user notifications, chat messages)
- Server Components: Use for data that needs to be fetched on the server without sending JavaScript to the client
Conclusion
Next.js provides flexible data fetching options that allow you to optimize your application for performance, SEO, and user experience. By choosing the right data fetching strategy for each part of your application, you can create fast, responsive web applications that provide a great user experience while maintaining good SEO.