Irbisa · Cheatsheet
Server Components & Next.js
React Server Components, server functions, CSR vs SSR vs SSG vs ISR, streaming, hydration errors, the Next.js App Router, caching
What are React Server Components, and how do they differ from Client Components?
// app/posts/[id]/page.tsx: a Server Componentexport default async function PostPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const post = await db.post.findUnique({ where: { id } }); if (!post) notFound();…What is the difference between CSR, SSR, SSG and ISR, and when would you choose each?
How do the App Router file conventions work:
page,layout,loading,errorandnot-found?// app/dashboard/error.tsx'use client'; export default function DashboardError({ error, reset,…What does
"use client"actually mark, and where should you put the boundary?// app/products/page.tsx: Server Componentexport default async function ProductsPage() { const products = await getProducts(); return ( <FilterPanel> {/* rendered on the server, passed through the client boundary */}…What can a Server Component pass as props to a Client Component, and what fails?
// app/posts/[id]/page.tsx: Server Componentexport default async function PostPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const commentsPromise = getComments(id); // not awaited: the page streams on return ( <Suspense fallback={<p>Loading comments...</p>}>…Find the bug: this page fails with "Event handlers cannot be passed to Client Component props."
// app/cart/page.tsxexport default async function CartPage() { const cart = await getCart(); return ( <div> <p>{cart.items.length} items</p> <button onClick={() => console.log('checkout', cart.id)}> Checkout </button> </div> );}How do you keep secrets and server-only code out of the client bundle in a Server Components app?
// lib/data/users.tsimport 'server-only'; export async function getProfile(userId: string) { const user = await db.user.findUnique({ where: { id: userId } }); if (!user) return null;…What are Server Functions (Server Actions), and how do you call one from a form?
// app/todos/actions.ts'use server'; export async function createTodo( _prev: { error?: string }, formData: FormData,…What are Route Handlers (
route.ts) in the App Router, and when do you use one instead of a Server Action?// app/api/webhooks/payments/route.ts: called by the payment provider, not by your UIexport async function POST(request: Request) { const body = await request.text(); // the raw body: the signature is computed over it const signature = request.headers.get('x-signature') ?? ''; if (!(await verifySignature(body, signature, process.env.PAYMENTS_WEBHOOK_SECRET!))) { return new Response('Invalid signature', { status: 400 });…What does
proxy.ts(formerlymiddleware.ts) do in Next.js 16, and what should you not put in it?// proxy.ts (Next.js 16; formerly middleware.ts with `export function middleware`)import { NextResponse, type NextRequest } from 'next/server'; export function proxy(request: NextRequest) { // optimistic check: no cookie means no session, so do not even render the page if (request.nextUrl.pathname.startsWith('/account') && !request.cookies.has('session')) {…How do you fetch data in Server Components, and how do you avoid request waterfalls?
export default async function DashboardPage() { // both requests start before either is awaited const [user, orders] = await Promise.all([getUser(), getOrders()]); return ( <>…How does streaming SSR work with
Suspenseandloading.tsx?// app/product/[id]/page.tsxexport default async function ProductPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const product = await getProduct(id); // fast: part of the first chunk return (…What causes a hydration mismatch error, and how do you fix one?
Find the bug: the theme button shows a hydration mismatch error, but only for users who chose the dark theme.
// ThemeToggle.tsx'use client'; export function ThemeToggle() { const saved = typeof window !== 'undefined' ? localStorage.getItem('theme') : null; const [theme, setTheme] = useState(saved ?? 'light'); return ( <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}> {theme === 'dark' ? 'Light mode' : 'Dark mode'} </button> );}When would you choose a client-side SPA (Vite and React Router) over Next.js with Server Components?
How do you handle SEO in the Next.js App Router:
metadata,generateMetadata,sitemap.tsand canonical URLs?// app/layout.tsxexport const metadata: Metadata = { metadataBase: new URL('https://shop.example'), title: { template: '%s | Shop', default: 'Shop' },};…Why is every Server Action a public endpoint, and how do you secure one?
// app/posts/actions.ts'use server'; const RenameInput = z.object({ postId: z.string().min(1), title: z.string().min(1).max(200) }); export async function renamePost(formData: FormData) {…How does caching work in the Next.js App Router, and what changed in Next.js 15 and 16?
import { cacheLife, cacheTag } from 'next/cache'; export async function getProducts(category: string) { 'use cache'; cacheLife('hours'); cacheTag('products', `products-${category}`);…After a mutation, how do you make the App Router show fresh data:
revalidatePath,revalidateTag,updateTagorrouter.refresh?'use server'; import { revalidateTag, updateTag } from 'next/cache'; export async function publishPost(postId: string) { await requireEditor();…What does React's
cache()do in Server Components, and how is it different from Next.js"use cache"?import { cache } from 'react'; export const getUser = cache(async (id: string) => { return db.user.findUnique({ where: { id } });});…Find the bug: after deploying, users sometimes see another user's name in the page header.
// lib/current-user.tslet currentUser: User | null = null; // the layout, the header and the page all call it: query the database only onceexport async function getCurrentUser() { if (!currentUser) { const session = await auth(); currentUser = await db.user.findUnique({ where: { id: session.userId } }); } return currentUser;} // app/Header.tsxexport async function Header() { const user = await getCurrentUser(); return <p>Signed in as {user?.name}</p>;}What does the server send for Server Components (the RSC payload), and how does the client use it on navigation?