Server Components: Fetch Data Directly
Server Components let you fetch data directly using `async/await`, simplifying code by removing client-side `useEffect` hooks. Use this for initial page loads in Next.js to improve SEO and performance. The footgun: don't use client-side hooks or browser APIs.
WHY IT EXISTS: Traditional client-side fetching in React apps often involves complex state management with hooks like useEffect and useState to handle loading, error, and data states. This can lead to content layout shifts as data arrives after the initial page load and can negatively impact SEO since search engine crawlers may not see the final content.
THE MENTAL MODEL: Treat a Server Component like a server-side script that outputs HTML. You can make the component's function async and await data from any source—a database, an external API, or the local filesystem—directly within its body. React and Next.js handle the underlying plumbing of fetching, caching the result, and streaming the final HTML to the client.
HOW IT WORKS: When a user requests a page, Next.js begins rendering the component tree on the server. If it encounters an async Server Component, rendering for that component and its children is paused until the awaited data fetch (the Promise) resolves. Next.js extends the native fetch API, automatically deduplicating identical requests and providing granular caching control. Once the data is available, the component finishes rendering its HTML, which is then streamed to the browser. This can be combined with React Suspense to show a loading fallback while data is being fetched.
WHEN TO USE IT: This is the default and recommended pattern for fetching the initial data required to render a page in the Next.js App Router. Use it whenever you need to get data from a database, a CMS, or any backend API. It's especially powerful for accessing resources that require secret keys or credentials, as those are never exposed to the client's browser.
WHEN NOT TO USE IT: This pattern is for server-side rendering. Do not use it for data that needs to be fetched or re-fetched based on client-side user interactions that happen after the page has loaded, such as live search, sorting a table, or submitting a form. Those scenarios are better handled by Client Components using traditional fetching methods or by using Server Actions.
ONE CANONICAL EXAMPLE: A product details page component can be an async function that receives a product ID from the URL params. Inside the component, it can await a call to a database or an e-commerce API to get the product's name, price, and description. It then directly renders this data into JSX. The entire process happens on the server, and the client receives a fully-formed HTML page.
Read the original → nextjs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.