Interview Bank · 2026

▲ Next.js

The App Router, Server vs Client Components, Server Actions, the caching layers, and the 2026 shift away from aggressive default caching. Say each answer aloud before you reveal it.

Rapid-fire flashcards flip to check

Click a card. Answer first, in one breath, then reveal.

App Router vs Pages Router?
App Router (the app/ dir) = Server Components by default, nested layouts, streaming. Pages Router (pages/) = the older client-first model with getServerSideProps. App Router is the default in 2026.
click to flip
Server vs Client Component?
Server Components render on the server, ship zero JS, can touch the DB/secrets. Client Components run in the browser — needed for state, effects, and event handlers.
click to flip
What does "use client" do?
A directive at the top of a file marking it (and its imports) as a Client Component — it opts that subtree into the browser bundle.
click to flip
What does "use server" do?
Marks a function (or file) as a Server Action — server-side code callable from the client, used for mutations.
click to flip
SSR vs SSG vs ISR?
SSR = render per request; SSG = render once at build; ISR = static, but revalidated/regenerated on a schedule so it stays fresh without a full rebuild.
click to flip
What is a Server Action?
An async server function ("use server") you can call directly from a form or event — handles mutations without you writing a separate API route.
click to flip
What is a Route Handler?
An API endpoint defined in app/api/.../route.ts via exported GET/POST functions — Next.js's built-in backend.
click to flip
What is layout.tsx?
Shared UI that wraps a route segment and its children, persisting across navigation (nav bars, shells). The root layout wraps the whole app.
click to flip
What's a dynamic route [id]?
A folder named [id] matches any value; the segment is passed in as params so one route handles /docs/1, /docs/2, etc.
click to flip
Why <Link> over <a>?
<Link> does client-side navigation (no full reload) and prefetches routes in view — fast, SPA-like transitions.
click to flip

Core questions

Server vs Client Components — when do you use each?

In the App Router everything is a Server Component by default: it renders on the server, ships no JS to the browser, and can read the database, files, or secrets directly. Reach for a Client Component ("use client") only when you need interactivity — useState/useEffect, event handlers, browser APIs. Rule of thumb: keep components on the server, push "use client" as far down the tree (the "leaves") as you can.

How do you fetch data in a Server Component?

Directly — the component can be an async function and you just await the data (a fetch, an ORM query, etc.) inline before returning JSX. No useEffect, no loading spinner plumbing, no separate API call from the client. The data is fetched on the server and only the rendered HTML goes to the browser, so credentials never leave the server.

How do you mutate data — and how do you refresh the UI after?

Use a Server Action ("use server"): an async function called from a form's action or an event handler that runs on the server. After writing, call revalidatePath("/docs") or revalidateTag("docs") to purge the cache for that data so the next render shows fresh content. This replaces hand-rolled POST endpoints + client refetch for most mutations.

How do environment variables work — server-only vs public?

By default env vars are server-only — readable in Server Components, Route Handlers, and Server Actions, never shipped to the browser. Only vars prefixed NEXT_PUBLIC_ are inlined into the client bundle and visible to anyone. So API keys and DB URLs stay un-prefixed; only truly public values (e.g. a public site URL) get NEXT_PUBLIC_.

What are Route Handlers, and when do you still need them?

app/api/.../route.ts exporting GET/POST/etc. gives you real HTTP endpoints — a backend-for-frontend. With Server Actions covering most form mutations, you reach for Route Handlers when you need a public API: webhooks, third-party callbacks, serving JSON to a mobile/external client, or anything that isn't a Next.js-internal call.

How does streaming work with Suspense and loading.tsx?

Next.js can stream HTML — send the shell immediately, then flush in slower parts as their data resolves. Wrap a slow component in <Suspense fallback={...}> to show a placeholder while it loads. A loading.tsx file is sugar for wrapping a whole route segment in Suspense, giving instant loading UI on navigation.

How do you handle metadata and SEO?

Export a static metadata object or an async generateMetadata() function from a layout or page — Next.js renders the <title>, meta, and Open Graph tags into the server-rendered HTML. Because pages are server-rendered, crawlers get real content. There's also file conventions like sitemap.ts, robots.ts, and opengraph-image.

What's the difference between SSR, SSG, and ISR?

SSG renders the page once at build time (fast, cacheable, great for content that rarely changes). SSR renders per request (always fresh, e.g. personalised pages). ISR serves static pages but revalidates them in the background on an interval or on demand — static speed with periodic freshness. In the App Router you pick these implicitly via your fetch/caching options rather than via getServerSideProps.

Theory deep-cuts the "why"

Why React Server Components at all? theory

Two big wins. Less JavaScript shipped: Server Components render to HTML on the server and send no component JS to the browser, shrinking the bundle and speeding up load. And data & secrets stay on the server: you query the DB or read an API key right inside the component, so credentials never reach the client and there's no client-server round-trip just to render. Interactivity is added back only where you opt into "use client".

What rendering strategies does Next.js offer? theory

Static (prerendered at build, cached), dynamic (rendered per request when you read cookies/headers or use uncached data), streaming (send the shell, flush slow parts via Suspense), and partial prerendering (a static shell with dynamic holes streamed in — the 2026 hybrid). You rarely pick one globally; it's decided per route segment by what the code reads.

Explain Next.js's caching layers. theory

Four, roughly outer-to-inner: Request Memoization (dedupes identical fetches within one render), the Data Cache (persists fetch results across requests/deploys until revalidated), the Full Route Cache (caches the rendered HTML/RSC payload of static routes), and the client-side Router Cache (keeps visited route segments in memory for instant back/forward). Knowing these explains "why is my data stale?" — you revalidate the right layer.

What is hydration? theory

The server sends static HTML so the page is visible fast; then React hydrates it in the browser — attaching event listeners and wiring up state so the static markup becomes interactive. Only Client Components hydrate. If the server-rendered HTML doesn't match what the client renders, you get a hydration mismatch error.

What is Partial Prerendering (PPR)? theory

A single route is split into a static shell (prerendered, served instantly from the edge) with dynamic holes wrapped in Suspense that stream in per request. One page gets both the speed of static and the freshness of dynamic, without choosing between them — the direction Next.js's rendering model is heading.

Tricky & gotchas where candidates trip

Why does useState in a Server Component throw? tricky

Hooks and event handlers only exist in the browser, but Server Components never run there. Calling useState/useEffect (or passing onClick) in one is an error: "you're importing a component that needs useState… add "use client"." Fix by marking the interactive piece "use client" — ideally a small leaf, not the whole page.

How does a secret leak via NEXT_PUBLIC_? tricky

Any var prefixed NEXT_PUBLIC_ is inlined into the client bundle at build time — anyone can read it in the browser. Naming your API key NEXT_PUBLIC_API_KEY ships it to every visitor. Secrets must stay un-prefixed and be read only on the server. "NEXT_PUBLIC_ = shouted to the browser."

What's surprising about fetch caching? tricky

Historically Next.js cached fetch by default, so data looked stale and people were baffled. You control it with { cache: 'no-store' } / { next: { revalidate: N } } / tags. In Next.js 15 the default flipped — fetches are uncached unless you opt in — so the gotcha now cuts the other way (you may need to add caching back for speed).

Why did adding "use client" blow up my bundle? tricky

"use client" marks a boundary: that component and everything it imports become client-side. Put it high in the tree and you accidentally drag the whole subtree into the browser bundle, losing the Server Component benefits. Keep the directive on small interactive leaves and pass server-rendered children in as props/children.

Are Server Actions automatically secure? tricky

No. A Server Action compiles to a public HTTP endpoint — anyone can call it with any payload, not just your form. Treat it like an API route: validate the input (e.g. with Zod) and check auth/authorisation inside the action. "It's only called from my button" is not a security control.

What causes a hydration mismatch? tricky

When the server-rendered HTML differs from the client's first render — e.g. rendering Date.now(), Math.random(), or reading window/localStorage during render, or invalid nesting like a <div> inside a <p>. Fix by making render deterministic, or deferring browser-only values to useEffect.

What's new in 2026 say this and stand out

What changed with caching in Next.js 15? 2026

The big shift was away from aggressive default caching. In Next.js 15, fetch requests, GET Route Handlers, and the client Router Cache are uncached by default — you now opt in to caching instead of opting out. It killed a whole class of "why is my data stale?" surprises; the trade-off is you sometimes add caching back deliberately for performance.

What are the async request APIs? 2026

Next.js 15 made the request-scoped APIs asynchronous: you now await cookies(), await headers(), and await params/searchParams. This supports the move toward partial prerendering (the static shell can render before per-request data arrives). It also ships React 19 support and Turbopack stable for dev (much faster local builds).

What about Partial Prerendering and after()? 2026

Partial Prerendering (PPR) is maturing — a static shell with dynamic, streamed holes in one route, no either/or. And after() lets you schedule work to run after the response is sent (logging, analytics, cache writes) without delaying the user. Frame both as: Next.js squeezing more out of the static/dynamic boundary.

Memory hooks "Server by default, client on demand." Everything's a Server Component until you reach for state, effects, or clicks — then "use client" on the leaf.
"NEXT_PUBLIC_ = shouted to the browser." Prefix it and it's public — secrets stay quiet (un-prefixed, server-only).
2026 = "caching is opt-IN now." Next 15 stopped caching your fetches behind your back.
Tie it to DocChat When asked "do you know Next.js?", point at the build: "DocChat's frontend is the App Router — Server Components fetch the documents straight from the API, a Server Action handles uploads with revalidatePath, the chat answer streams in via Suspense, and my OpenAI key stays server-only (never NEXT_PUBLIC_)." Concrete beats abstract.