How to Fetch Data in Next.js: Simple Guide with Examples
In Next.js, you can fetch data on the server using
getServerSideProps or getStaticProps for static generation, and on the client using React hooks like useEffect with fetch. These methods let you load data before or after the page renders, depending on your needs.Syntax
Next.js provides special functions to fetch data before rendering pages:
- getStaticProps: Fetches data at build time for static pages.
- getServerSideProps: Fetches data on each request for server-side rendering.
- Client-side fetching: Use React's
useEffecthook withfetchto load data after the page loads.
Each function returns props that the page component receives.
javascript
export async function getStaticProps() { const res = await fetch('https://api.example.com/data') const data = await res.json() return { props: { data } } } export async function getServerSideProps() { const res = await fetch('https://api.example.com/data') const data = await res.json() return { props: { data } } } import { useEffect, useState } from 'react' function Page() { const [data, setData] = useState(null) useEffect(() => { fetch('https://api.example.com/data') .then(res => res.json()) .then(setData) }, []) if (!data) return <p>Loading...</p> return <div>{JSON.stringify(data)}</div> } export default Page;
Example
This example shows how to fetch data at build time using getStaticProps and display it in a Next.js page.
javascript
export async function getStaticProps() { const res = await fetch('https://jsonplaceholder.typicode.com/posts/1') const post = await res.json() return { props: { post } } } export default function PostPage({ post }) { return ( <main> <h1>{post.title}</h1> <p>{post.body}</p> </main> ) }
Output
<main>
<h1>sunt aut facere repellat provident occaecati excepturi optio reprehenderit</h1>
<p>quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto</p>
</main>
Common Pitfalls
Common mistakes when fetching data in Next.js include:
- Using
fetchdirectly inside the component withoutuseEffect, causing infinite loops. - Not returning an object with
propsfromgetStaticPropsorgetServerSideProps. - Trying to use browser-only APIs like
windowinside server-side functions. - Not handling loading states in client-side fetching.
javascript
/* Wrong: fetch called directly in component body (causes infinite loop) */ import { useState } from 'react' function Page() { const [data, setData] = useState(null) fetch('https://api.example.com/data') .then(res => res.json()) .then(setData) if (!data) return <p>Loading...</p> return <div>{JSON.stringify(data)}</div> } /* Right: fetch inside useEffect to run once after mount */ import { useEffect, useState } from 'react' function Page() { const [data, setData] = useState(null) useEffect(() => { fetch('https://api.example.com/data') .then(res => res.json()) .then(setData) }, []) if (!data) return <p>Loading...</p> return <div>{JSON.stringify(data)}</div> } export default Page;
Quick Reference
Summary of Next.js data fetching methods:
| Method | When to Use | Runs On | Example Function |
|---|---|---|---|
| Static Generation | Build time, for static pages | Server (build) | getStaticProps |
| Server-side Rendering | Every request, dynamic data | Server (request) | getServerSideProps |
| Client-side Fetching | After page loads, user interaction | Browser | useEffect + fetch |
Key Takeaways
Use getStaticProps to fetch data at build time for fast static pages.
Use getServerSideProps to fetch data on each request for dynamic content.
Use useEffect with fetch for client-side data loading after page render.
Always handle loading states when fetching data on the client.
Avoid calling fetch directly in the component body to prevent infinite loops.