Next.js Interview Mock sample questions with answers

10 questions from the Next.js Interview Mock practice bank, spread across its domains. Pick your answer, then open the explanation to see why each option is right or wrong.

  1. Question 1Rendering, Data and Mutations

    Which of these make a Server Action's response include a freshly rendered RSC payload for the current route? (Choose three.)

    Choose 3.

    • A

      Calling updateTag('cart')

    • B

      Calling refresh()

    • C

      Calling (await cookies()).delete('promo')

    • D

      Calling revalidateTag('cart', 'max')

    • E

      Returning { ok: true } without calling anything else

    • F

      Calling after(() => log()) from next/server

    Show the answer and explanation

    Answer: A and B and C

    A re-render is included when the action calls updateTag, revalidatePath or refresh, mutates cookies, or calls redirect, which streams the destination. revalidateTag with a stale-while-revalidate profile is the documented exception.

    Why the other options are wrong

    • D. Stale-while-revalidate skips the immediate re-render; later reads see the change.

    • E. Then the response carries only the return value.

    • F. after schedules work after the response; it doesn't trigger a re-render.

  2. Question 2Production Next.js

    A blog post page is marked 'use client' so it can syntax-highlight code with a large library and open a share modal. The client bundle is huge. Which two changes reduce the JavaScript shipped? (Choose two.)

    Choose 2.

    • A

      Do the highlighting in a Server Component, since it needs no browser APIs

    • B

      Lazy-load the modal with next/dynamic so its code loads on demand

    • C

      Enable reactCompiler, which strips unused libraries from client bundles

    • D

      Add lucide-react to optimizePackageImports to shrink the highlighter

    • E

      Move 'use client' up into the root layout so code is shared

    Show the answer and explanation

    Answer: A and B

    The Next.js bundling guide calls out exactly this case: libraries that only turn data into UI, such as highlighters, chart renderers and markdown parsers, can run in Server Components, so none of their code reaches the client. Interaction-only pieces like a modal can be deferred with next/dynamic or React.lazy. Keep 'use client' boundaries as low and as small as possible.

    Why the other options are wrong

    • C. The React Compiler memoizes rendering; it doesn't remove dependencies.

    • D. Unrelated, and lucide-react is already optimized by default.

    • E. That puts even more of the tree into the client bundle.

  3. Question 3Routing and Navigation

    A page wraps const user = await getUser(id) in try { ... } catch (e) { console.error(e) }, and getUser calls notFound() when no user exists. For a missing user, the route's not-found.tsx is still rendered.

    • A

      True

    • B

      False

    Show the answer and explanation

    Answer: B

    notFound() throws a special NEXT_HTTP_ERROR_FALLBACK;404 error that has to reach Next.js. A try/catch around the call swallows it, so the not-found UI never renders. Either let the error propagate, or call unstable_rethrow(e) at the top of the catch block so framework errors from notFound() and redirect() pass through.

    Why the other options are wrong

    • A. notFound() works by throwing, so the catch block swallows it.

  4. Question 4Server and Request Handling

    A handler logs the body and then validates it. The second line throws a TypeError. Why, and what is the fix?

    export async function POST(request: Request) {
      console.log(await request.json())
      const raw = await request.text()
      // ...
    }
    • A

      A body can be read once; call request.clone() before reading it

    • B

      You can't call text() after json(), but calling json() twice works

    • C

      console.log locks the request, so log it after reading text()

    • D

      Next.js gives route handlers a pre-parsed body, so text() is unavailable

    Show the answer and explanation

    Answer: A

    A Web Request body is a stream that can be consumed only once. After request.json(), any further read throws "Body is unusable" or "Body has already been read". Read it once and reuse the value, or call request.clone() first and read the clone separately.

    Why the other options are wrong

    • B. Any second read of the same body fails, whichever method you use.

    • C. Logging has nothing to do with it; the first body read consumed the stream.

    • D. The handler gets an unread Web Request; its body methods all work, once.

  5. Question 5Rendering, Data and Mutations

    When Draft Mode is enabled, every "use cache" function and component re-executes on each request, and the results are not written to the cache.

    • A

      True

    • B

      False

    Show the answer and explanation

    Answer: A

    With Draft Mode on, cached functions run every time and nothing is saved, so editors see unpublished content immediately. You may read isEnabled from draftMode() inside a use cache scope, but other request APIs are still forbidden. Calling enable() or disable() inside a cache scope throws.

    Why the other options are wrong

    • B. Draft Mode does bypass the cache; the docs describe it as always-fresh for cached functions.

  6. Question 6Production Next.js

    After login, a Client Component runs router.push(searchParams.get('next') ?? '/'). Why is this dangerous even though React 19 blocks javascript: URLs in href?

    • A

      It is not dangerous: router.push only accepts paths inside the app

    • B

      A javascript: URL passed to router.push executes in the page

    • C

      It leaks the session cookie in the Referer header to the next page

    • D

      It disables prefetching, which lets the attacker race the navigation

    Show the answer and explanation

    Answer: B

    React's javascript: protection applies to rendered attributes such as href and src. Programmatic navigation is different: the useRouter docs say javascript: URLs sent to router.push or router.replace are executed in the context of your page. Treat next, callbackUrl and similar parameters as untrusted. Accept only same-origin relative paths (and reject //), or map them to an allowlist.

    Why the other options are wrong

    • A. router.push accepts full URLs, including other schemes.

    • C. Cookies are not sent in the Referer header.

    • D. Prefetching has nothing to do with the injection.

  7. Question 7Routing and Navigation

    A Pages Router app adds getInitialProps to pages/_app.tsx to load the current user for every page. What side effect does this have?

    • A

      None, because data fetching in _app runs only once at build time and then gets cached

    • B

      It disables Automatic Static Optimization for pages without getStaticProps

    • C

      It turns every page into a Client Component

    • D

      Next.js ignores it, because _app can't fetch data

    Show the answer and explanation

    Answer: B

    Using getInitialProps in a custom App disables Automatic Static Optimization for pages that do not use getStaticProps, so they are rendered on every request. App does not support getStaticProps or getServerSideProps, and the docs recommend moving such logic to the App Router rather than using this pattern.

    Why the other options are wrong

    • A. getInitialProps runs per request on the server, and again on client navigations.

    • C. Pages Router pages are not Server or Client Components in the App Router sense.

    • D. _app does not support getStaticProps or getServerSideProps, but getInitialProps does run.

  8. Question 8Server and Request Handling

    In Next.js 16 without Cache Components, which of these exports in a route.ts file are valid route segment config? (Choose three.)

    Choose 3.

    • A

      export const dynamic = 'force-static'

    • B

      export const revalidate = 60

    • C

      export const maxDuration = 30

    • D

      export const config = { api: { bodyParser: false } }

    • E

      export const methods = ['GET', 'POST']

    • F

      export const cache = 'force-cache'

    Show the answer and explanation

    Answer: A and B and C

    Route Handlers take the same route segment config as pages and layouts: dynamic, dynamicParams, revalidate, fetchCache, runtime and maxDuration. With Cache Components enabled in v16, dynamic, dynamicParams, revalidate and fetchCache are removed in favour of use cache.

    Why the other options are wrong

    • D. That is Pages Router API Routes config; route handlers ignore it.

    • E. Methods are declared by exporting functions, not by a config array.

    • F. cache is a fetch option, not a route segment config export.

  9. Question 9Rendering, Data and Mutations

    A Server Component calls fetch(url, { cache: "force-cache" }). Which statements are true? (Choose two.)

    Choose 2.

    • A

      Requests that differ only in headers get separate cache entries

    • B

      Only responses with a 200 status are stored

    • C

      POST requests are never cached, even with this option

    • D

      Requests that send an authorization header are skipped

    • E

      The entry is dropped on every deploy like a use cache entry

    Show the answer and explanation

    Answer: A and B

    force-cache looks for a matching request in the server-side cache, matching on URL, method, headers and body. A fresh match is returned, a missing or stale one is fetched again, and only 200 responses are stored. Caching is opt-in and applies even to POST and authorized requests, so think about data sensitivity. Draft Mode bypasses the cache entirely.

    Why the other options are wrong

    • C. With force-cache any request can be cached, including POST.

    • D. The docs say they are cached too, so be deliberate about it.

    • E. The fetch cache is the documented way to persist across deploys.

  10. Question 10Production Next.js

    Where do you call registerOTel({ serviceName: "next-app" }) from @vercel/otel?

    • A

      At the top of app/layout.tsx, so tracing starts before any page in the app is rendered

    • B

      Inside the proxy function in proxy.ts

    • C

      In next.config.ts, inside an experimental.otel block

    • D

      Inside the register function exported from instrumentation.ts at the project root

    Show the answer and explanation

    Answer: D

    Create instrumentation.ts in the root of the project, or inside src alongside app, but not inside app or pages. Export a register function that calls registerOTel. If you use a pageExtensions suffix, the instrumentation file name must use it too.

    Why the other options are wrong

    • A. Layouts render per request; instrumentation needs a one-time server hook.

    • B. Proxy runs per request and is not the documented setup hook.

    • C. There is no such config; setup happens in the instrumentation file.

Practise all 494 NEXT questions

Start with the free 15-question diagnostic. It shows where to focus, and your results carry over if you sign up.

Go to NEXT