Tags: next.js, react, ssr, ssg, isr, app-router, server-components
Level: intermediate
TL;DR: Full-stack React framework optimized for production: App Router by default, React Server Components, hybrid rendering strategies, and zero-config routing.
App Router relies on directory structure inside app/ using React Server Components by default.
Server Components render exclusively on server; zero client-side JavaScript sent for their code.
Client Components declare 'use client' directive at top; handle state, effects, and event listeners.
Static Site Generation builds HTML at compile time; served instantly via CDN.
Server-Side Rendering renders fresh HTML per request using dynamic functions or { cache: 'no-store' }.
Incremental Static Regeneration updates static pages in background without full rebuild using revalidate.
Route Handlers define custom request handlers via route.ts using standard Web Request/Response APIs.
Middleware intercepts requests globally for auth checks, redirects, and header manipulation.
Built-in optimizations include <Image>, next/font, and <Link> with automatic viewport prefetching.
Server Actions allow direct server mutations from forms or functions without manual API routes.
Q: How do React Server Components differ from standard SSR?R: SSR sends pre-rendered HTML plus full JS bundle to hydrate everything. RSC executes on the server, streams HTML/JSON payload, and keeps component code out of the client bundle completely.
Q: When should you use a Client Component in App Router?R: I keep components on the server by default and add 'use client' only when I need browser APIs, React state, effects, or user event listeners.
Q: How does data caching and revalidation work in Next.js?R: Data fetches are cached by default in fetch requests; I invalidate them using time-based revalidation via next: { revalidate: seconds } or on-demand using revalidateTag and revalidatePath.
Q: What is the difference between Server Actions and Route Handlers?R: Route Handlers expose public REST endpoints (route.ts). Server Actions are async functions called directly from client UI or forms for transactional mutations.
Importing server-only secrets or database clients inside files without isolating them from Client Components.
Placing 'use client' at the root layout instead of pushing client boundaries down to leaf components.
Using window, localStorage, or document directly inside component body before mounting.
Forgetting that dynamic functions like cookies() or headers() opt routes out of static generation.
Overusing Route Handlers for standard mutations instead of idiomatic Server Actions.
# Project initialization
npx create-next-app@latest my-app --typescript --tailwind --app
npm run dev
npm run build
TypeScript
// app/users/page.tsx - React Server Component with caching
interface User {
id: string;
name: string;
}
export default async function UsersPage() {
const res = await fetch('https://api.example.com/users', {
next: { revalidate: 60, tags: ['users-list'] }
});
const users: User[] = await res.json();
return (
<ul>
{users.map((u) => (
<li key={u.id}>{u.name}</li>
))}
</ul>
);
}
TypeScript
// app/actions.ts - Server Action
'use server';
import { revalidateTag } from 'next/cache';
export async function updateUser(formData: FormData) {
const name = formData.get('name') as string;
// db mutation here
revalidateTag('users-list');
}
[ ] Deep dive into Parallel Routes (@slot) and Intercepting Routes ((.)route)
[ ] Partial Prerendering (PPR) configuration and streaming with Suspense
[x] Server Components vs Client Components boundaries
[x] Basic Route Handlers and middleware configuration
Next.js Documentation (nextjs.org/docs)
React Server Components Specifications