nextjs-server-components
When building Next.js App Router pages and deciding between Server and Client Components.
When & Why to Use This Skill
This Claude skill provides expert guidance on navigating the Next.js App Router architecture, specifically helping developers strategically decide between React Server Components (RSC) and Client Components. It focuses on optimizing performance, enhancing security by keeping sensitive logic on the server, and reducing client-side JavaScript bundles through proven design patterns and best practices.
Use Cases
- Architecting Next.js pages to determine the optimal boundary between Server and Client Components for maximum performance.
- Implementing secure data fetching patterns that keep database queries and API secrets strictly on the server side.
- Refactoring existing components to resolve anti-patterns, such as unnecessary 'use client' directives or improper prop serialization.
- Applying the Composition Pattern to build complex UIs where interactive Client Components are nested within high-performance Server Components.
- Optimizing Core Web Vitals by leveraging parallel data fetching and zero-bundle-size components in the App Router.
| name | nextjs-server-components |
|---|---|
| description | When building Next.js App Router pages and deciding between Server and Client Components. |
| version | 1.0.0 |
| tokens | ~450 |
| confidence | high |
| - https | //react.dev/reference/rsc/server-components |
| last_validated | 2025-01-10 |
| next_review | 2025-01-24 |
| tags | [nextjs, react, rsc, server-components, frontend] |
When to Use
When building Next.js App Router pages and deciding between Server and Client Components.
Patterns
Default: Server Components
// app/page.tsx - Server Component by default
async function Page() {
const data = await db.query('SELECT * FROM posts');
return <PostList posts={data} />;
}
// ✅ Direct DB/API access
// ✅ Secrets safe (never sent to client)
// ✅ Zero client JS for this component
Client Component ("use client")
'use client'
// Only add when you NEED:
// - useState, useEffect, useContext
// - Event handlers (onClick, onChange)
// - Browser APIs (localStorage, window)
import { useState } from 'react';
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
Composition Pattern
// Server Component (parent)
async function Dashboard() {
const user = await getUser();
return (
<div>
<UserInfo user={user} /> {/* Server */}
<InteractiveChart /> {/* Client */}
</div>
);
}
// Pass server data to client as props
<ClientComponent initialData={serverData} />
Data Fetching in Server Components
// ✅ Parallel fetching
async function Page() {
const [posts, user] = await Promise.all([
getPosts(),
getUser()
]);
return <Feed posts={posts} user={user} />;
}
Anti-Patterns
- Adding "use client" to every component (defeats RSC benefits)
- Importing server-only code in client components
- Passing functions as props from Server to Client
- Using useEffect for data that could be fetched on server
Verification Checklist
- "use client" only where actually needed
- No secrets in client components
- Server data passed as serializable props
- Parallel data fetching where possible