Next.js Server Components
Render on the server by default with async data fetching and zero client JS
Overview
Server Components run only on the server. They can be async, access databases directly, and do not ship component logic to the browser. Use them by default; add Client Components only when you need interactivity.
Syntax / Usage
// Server Component (default — no directive)
async function ProductList() {
const products = await db.products.findMany()
return (
<ul>
{products.map((p) => (
<li key={p.id}>{p.name}</li>
))}
</ul>
)
}
// Fetch in Server Component
async function Page() {
const res = await fetch('https://api.example.com/posts', {
next: { revalidate: 60 },
})
const posts = await res.json()
return <PostList posts={posts} />
}
Server Components can import Client Components as children, but not vice versa directly.
Examples
Stream data with Suspense:
import { Suspense } from 'react'
export default function Page() {
return (
<Suspense fallback={<Skeleton />}>
<SlowData />
</Suspense>
)
}
async function SlowData() {
const data = await fetchAnalytics()
return <Chart data={data} />
}
Pass server data to a client form:
// Server
export default async function EditPage({ params }) {
const user = await getUser(params.id)
return <EditForm user={user} />
}
// Client child receives serialized props
'use client'
function EditForm({ user }: { user: User }) { /* ... */ }
Common Mistakes
- Using hooks (
useState,useEffect) in Server Components - Passing non-serializable props (functions, class instances) to Client Components
- Fetching the same data in both layout and page without caching/deduping
- Marking entire trees
'use client'when only a leaf needs it
See Also
client-components app-router routing api-routes