Ace your Next.js interview with 45+ questions on App Router, Server Components, rendering strategies, and production deployment.
Pages Router (legacy): file-based routing in /pages, getServerSideProps/getStaticProps for data fetching, client components by default. App Router (Next.js 13+, stable in 14): routing via /app directory, layouts, React Server Components by default, new data fetching with async/await directly in components, Server Actions, streaming. Use App Router for new projects; Pages Router still supported.
Middleware runs at the edge before requests hit your routes. Use for: authentication/authorization redirects, A/B testing, geolocation redirects, rate limiting, rewriting URLs, setting headers. Based on the Edge Runtime (not full Node.js). Cannot access filesystem or Node.js APIs directly. Keep middleware fast and simple — it runs on every request. Use NextResponse.redirect, rewrite, next.
Layouts (layout.tsx) wrap pages and preserve state across navigation — don't re-render when child route changes. Root layout: required, wraps entire app. Nested layouts: each route segment can have its own layout. Use for: persistent sidebars, navigation, auth wrappers. Layouts receive children prop. Loading.tsx creates automatic Suspense boundaries. Error.tsx catches errors in segment.
Server Components run on the server, never shipped to browser. Benefits: direct backend access (DB, filesystem), smaller JS bundle, sensitive data stays server-side. Limitations: no useState, no event handlers, no browser APIs. Client Components ("use client"): interactive, have state, run in browser. Default in App Router is Server Component. Compose: Server Components can render Client Components, not vice-versa.
Static (SSG): rendered at build time, fastest, CDN-cacheable — use for marketing pages. Dynamic (SSR): rendered on each request — use for personalized pages. Incremental Static Regeneration (ISR): static + revalidate on interval — best of both. Client-side: via useEffect after hydration. App Router: every component is static by default; opt into dynamic with dynamic = "force-dynamic" or reading request data.
ISR rebuilds static pages in the background after a time interval without full rebuild. In Pages Router: revalidate in getStaticProps. In App Router: fetch(url, {next: {revalidate: 60}}) or export const revalidate = 60 at segment level. On-demand revalidation: revalidatePath() or revalidateTag() from Server Actions/API routes. Use for: frequently changing content (prices, inventory) that still benefits from static performance.
Server Actions are async functions that run on the server, called from client components. Define with "use server" directive. Used for: form submissions (progressive enhancement), mutations, calling databases directly. No API route needed. Integration: as form action prop, or called directly in event handlers. Return data or use React state for optimistic updates. Validated and secured on server.
generateStaticParams (App Router): returns array of param objects for static generation — replaces getStaticPaths. Called at build time. Dynamic routes without generateStaticParams are dynamically rendered (or use dynamicParams config). dynamic = "force-static" ignores dynamic functions. dynamic = "force-dynamic" always re-renders. Use generateStaticParams for known params at build time (blog posts, product pages).
Four caching layers: (1) Request Memoization (deduplicates fetch in a render pass), (2) Data Cache (persists fetch results across requests, revalidated with revalidate or tags), (3) Full Route Cache (stores rendered HTML/RSC payload at build time), (4) Router Cache (client-side cache of visited segments). Use revalidatePath/revalidateTag for on-demand revalidation. Understanding caching is crucial for correct Next.js behavior.
Options: (1) NextAuth.js / Auth.js — handles OAuth providers, credentials, JWT, database sessions with minimal config, (2) Clerk — hosted auth with UI components, (3) Custom — JWT in httpOnly cookies via middleware. Middleware (middleware.ts): runs at the edge before requests, ideal for auth redirects. Use session in Server Components via auth(). Protect both pages and API routes.
Use next/image instead of <img>. Benefits: automatic WebP/AVIF conversion, lazy loading, prevents layout shift (width/height required), responsive sizing via sizes prop. Optimization: srcset generated automatically, images served from /_next/image endpoint, CDN cacheable. For external images: add domains to next.config.js images.remotePatterns. Use priority prop for above-the-fold images.
Streaming progressively renders and sends HTML to the client — user sees content sooner, no waiting for full page. App Router enables streaming by default. Use loading.tsx for route-level streaming. Wrap slow components in <Suspense fallback={<Spinner/>}> for granular streaming. Server Components can be async — await slow data, render progressively. Combine with priority: fast UI shell first, slow data streams in.
NEXT_PUBLIC_ prefix: exposed to browser. Without prefix: server-only. Load order: .env, .env.local (gitignored), .env.development/.production (environment-specific). Access: process.env.VAR_NAME. In App Router Server Components, all env vars accessible without NEXT_PUBLIC_. Runtime env vs build-time: NEXT_PUBLIC_ vars are inlined at build — for runtime vars on Vercel, use process.env without prefix in server code.
Pages Router: /pages/api/route.ts exports handler(req, res). App Router: /app/api/route/route.ts exports named functions GET, POST, etc. (Route Handlers). Route Handlers: receive Request, return Response (Web standard). Access dynamic params via params. Use for: webhooks, form processing, third-party API proxying. Prefer Server Actions over API routes for form submissions in App Router.
App Router: Metadata API — export metadata object or generateMetadata function from layout/page. Supports: title, description, openGraph, twitter, robots, canonical, alternates. generateMetadata can be async (fetch data). Pages Router: use next/head. Sitemap: generate via app/sitemap.ts returning MetadataRoute.Sitemap. Robots.txt: app/robots.ts. Use layout-level metadata for defaults, page-level for overrides.
Practice with interactive quizzes and get instant feedback.
Start Free Practice