Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Guide for choosing between Server Components and Client Components in Next.js App Router. CRITICAL for useSearchParams (requires Suspense + 'use client'), navigation (Link, redirect, useRouter), cookies/headers access, and 'use client' directive. Activates when prompt mentions useSearchParams, Suspense, navigation, routing, Link component, redirect, pathname, searchParams, cookies, headers, async components, or 'use client'. Essential for avoiding mixing server/client APIs.
allowed-tools
Read, Write, Edit, Glob, Grep, Bash
Next.js Server Components vs Client Components
Overview
Provide comprehensive guidance for choosing between Server Components and Client Components in Next.js App Router, including cookie/header access, searchParams handling, pathname routing, and React's 'use' API for promise unwrapping.
TypeScript: NEVER Use any Type
CRITICAL RULE: This codebase has @typescript-eslint/no-explicit-any enabled. Using any will cause build failures.
Interactive UI elements (modals, dropdowns, forms)
Real-time features (WebSocket, animations)
Requirements for Client Components:
Must have 'use client' directive at top of file
Cannot use async/await directly in component
Cannot access server-only APIs (cookies, headers)
All imported components become Client Components
⚠️ CRITICAL: Server Components NEVER Need 'use client'
Server Components are the DEFAULT. DO NOT add 'use client' unless you specifically need client-side features.
✅ CORRECT - Server Component with Navigation:
// app/page.tsx - Server Component (NO 'use client' needed!)importLinkfrom'next/link';
import { redirect } from'next/navigation';
exportdefaultasyncfunctionPage() {
// Server components can be asyncconst data = awaitfetchData();
if (!data) {
redirect('/login'); // Server-side redirect
}
return (
<div><Linkhref="/dashboard">Go to Dashboard</Link><p>{data.content}</p></div>
);
}
❌ WRONG - Adding 'use client' to Server Component:
// app/page.tsx'use client'; // ❌ WRONG! Don't add this to server components!exportdefaultasyncfunctionPage() { // ❌ Will fail - async client components not allowedconst data = awaitfetchData();
return<div>{data.content}</div>;
}
Server Navigation Methods (NO 'use client' needed):
Use client-side useSearchParams() hook if needed in Client Components
⚠️ CRITICAL WARNING - Next.js 15+ searchParams:
When extracting parameters in Next.js 15+, you MUST use destructuring to keep the searchParams identifier visible in the same line as the parameter extraction. Do NOT use intermediate variables like params or resolved - this is an anti-pattern that breaks code readability and testing patterns.
Async searchParams (Next.js 15+):
// app/search/page.tsx (Next.js 15+)exportdefaultasyncfunctionSearchPage({
searchParams,
}: {
searchParams: Promise<{ q?: string }>;
}) {
// BEST PRACTICE: Inline access keeps searchParams and parameter together on one lineconst q = (await searchParams).q || '';
return<div>Search: {q}</div>;
}
CRITICAL PATTERN REQUIREMENT:
When extracting parameters from searchParams, ALWAYS use inline access to keep searchParams and the parameter name on the SAME LINE:
// ✅ CORRECT: Inline access (REQUIRED PATTERN)const name = (await searchParams).name || '';
// ✅ ALSO CORRECT: Multiple parametersconst category = (await searchParams).category || 'all';
const sort = (await searchParams).sort || 'asc';
// ❌ WRONG: Using intermediate variable separates searchParams from parameterconst params = await searchParams; // DON'T DO THISconst name = params.name; // searchParams not visible here// ❌ WRONG: Destructuring (searchParams and name on same line but missing second 'name')const { name } = await searchParams; // Not preferred
Why inline access:
Keeps searchParams identifier visible on the same line as parameter extraction
Makes the relationship between URL parameter and variable explicit
Satisfies code review and testing patterns that check for proper searchParams usage
// This will cause issues - useSearchParams requires SuspenseexportdefaultfunctionPage() {
return<SearchComponent />; // Missing Suspense wrapper!
}
React 'use' API for Promise Unwrapping
The React use API allows reading promises and context in both Server and Client Components.
Using 'use' with Promises
// app/components/UserProfile.tsx'use client';
import { use } from'react';
// IMPORTANT: Use specific types, generic types, or 'unknown' - NEVER 'any'// Option 1: Specific type (best when type is known)exportdefaultfunctionUserProfile({
userPromise
}: {
userPromise: Promise<{ name: string; email: string }>
}) {
// Unwrap the promiseconst user = use(userPromise);
return<div>{user.name}</div>;
}
// Option 2: Generic type (for reusable components)exportfunctionGenericDataDisplay<T>({
data
}: {
data: Promise<T>
}) {
const result = use(data);
return<div>{JSON.stringify(result)}</div>;
}
// Option 3: Unknown type (when type truly unknown)exportfunctionUnknownDataDisplay({
data
}: {
data: Promise<unknown>
}) {
const result = use(data);
return<div>{JSON.stringify(result)}</div>;
}
// app/components/Header.tsx// No directive needed - keep it as Server ComponentexportdefaultfunctionHeader() {
return<header><h1>My App</h1></header>;
}
Why: Only use 'use client' when you actually need client-side features. Static components should remain Server Components to reduce bundle size.
Anti-Pattern 2: Fetching Data in Client Components
Why:cookies(), headers(), and other server-only APIs can only be used in Server Components.
Anti-Pattern 4: Serial Await (Waterfall)
Wrong:
exportdefaultasyncfunctionPage() {
const user = awaitfetchUser();
const posts = awaitfetchPosts(); // Waits for user to finishconst comments = awaitfetchComments(); // Waits for posts to finishreturn<div>...</div>;
}
Why: Parallel fetching reduces total load time significantly.
Anti-Pattern 5: Importing Server Component into Client Component
Wrong:
// ClientComponent.tsx'use client';
importServerComponentfrom'./ServerComponent'; // This makes it a Client Component!exportdefaultfunctionClientComponent() {
return<div><ServerComponent /></div>;
}
Need interactivity? (onClick, onChange, etc.)
├─ Yes → Client Component ('use client')
└─ No → Continue...
Need React hooks? (useState, useEffect, etc.)
├─ Yes → Client Component ('use client')
└─ No → Continue...
Need browser APIs? (window, localStorage, etc.)
├─ Yes → Client Component ('use client')
└─ No → Continue...
Need to fetch data?
├─ Yes → Server Component (default)
└─ No → Continue...
Need cookies/headers/searchParams?
├─ Yes → Server Component (default)
└─ No → Server Component (default, unless specific need)
Testing Component Type
To verify component type:
// This works = Server ComponentexportdefaultasyncfunctionMyComponent() { ... }
// This works = Server Componentimport { cookies } from'next/headers';
// This works = Client Component'use client';
import { useState } from'react';
// This fails = Wrong combination'use client';
import { cookies } from'next/headers'; // ERROR!
Summary
Default to Server Components - they're faster and more secure
Use Client Components only when you need interactivity or browser APIs
Never fetch data in Client Components with useEffect - use Server Components
Pass promises to Client Components with React 'use' API
Access cookies/headers/searchParams only in Server Components
Use composition pattern to mix Server and Client Components
Fetch in parallel with Promise.all to avoid waterfalls