Skip to content
Chapter 34Lesson 9

Quiz - Project config, platform primitives, and SEO

Quiz progress

0 / 0

You install a database driver, import it in a route handler, and the dev server crashes with Cannot find module 'pg-native'. Before reaching for serverExternalPackages, what should you check first?

Whether the package is already on Next’s built-in external list — most popular Node SDKs (@prisma/client, pg, sharp, and ~80 more) are externalized for you, so adding a config line would be redundant cold-start tax.
Whether the package belongs in transpilePackages instead — a native-binding crash is the signature of a raw-TypeScript package Next needs to compile in.
Whether you should preemptively externalize every database driver, since native bindings are known to break bundling and it’s safer to list them up front.

A product card renders a thumbnail with fill inside a responsive grid, and your reviewer flags it as the single most common next/image performance bug. What’s missing?

A sizes prop — without it the browser can’t know how wide the image renders, so it plays safe and downloads the largest variant in the srcset, defeating the optimization entirely.
The preload prop — a fill image has no intrinsic dimensions, so it can’t reserve its box and reduce CLS until it’s told to preload.
Explicit width and height props — fill still needs them to compute the aspect ratio the layout reserves.
A quality value plus a matching qualities entry in next.config.ts, since fill images skip the default 75.

Four URL rules land on your desk. Mark each rule that belongs in next.config.ts (redirects/rewrites) rather than proxy.ts or a redirect() call. Select all that apply.

Permanently move /account/:path* to /settings/:path* for every visitor after a rebrand.
Serve /docs/* from an upstream docs origin while the URL stays on your domain.
Bounce a logged-out-looking visitor (no session_token cookie present) off /app to /welcome.
Send the user to a newly created invoice’s page the moment a Server Action finishes saving it.

You wire a brand display face through next/font/local and reach for the font-display Tailwind utility, but the class does nothing. Where’s the bug most likely to be?

The font’s variable CSS custom property is never aliased into a Tailwind token via @theme in globals.css, so no font-display utility is generated.
There’s no fontFamily: { display: [...] } entry in tailwind.config.ts, which is where v4 registers font tokens.
The loader is missing subsets: ['latin'], which is required for local fonts and blocks the build until added.

Marketing pastes a retargeting pixel into the root app/layout.tsx with strategy="beforeInteractive". The build is green and the pixel fires. What’s the actual problem?

It now runs ahead of hydration on every route, stealing the main thread from your own code and dragging LCP site-wide — and it can fire before the user has answered the consent banner.
Without an id, Next can’t dedupe an external script, so the pixel reloads on every navigation within the layout.
beforeInteractive is illegal outside a route group, so placing it in the root layout is the one mistake here that should have failed the build.

An invoice detail page reads the same invoice in three places on one request: generateMetadata, the page body, and opengraph-image.tsx. With the read helper wrapped in React’s cache(), how many times does Postgres get queried for that invoice across two back-to-back requests for the same invoice?

Twice — once per request. cache() collapses the three reads within each request into one, but the store is discarded when each request ends.
Once total — the first request caches the row and the second reads it straight from memory without touching the database.
Six times — every consumer in every request queries independently, since cache() only applies once a route is statically optimized.

A robots.ts gates indexing on the environment so preview deploys stay invisible. A teammate writes if (process.env.NODE_ENV === 'production') as the discriminator. Why is that the wrong check on Vercel?

A Vercel preview deploy is a production build, so NODE_ENV is 'production' there too — the gate would leave every preview indexable. VERCEL_ENV is the signal that distinguishes production from preview.
NODE_ENV isn’t available inside robots.ts because it runs as a cached route handler at the edge, so the branch silently evaluates to undefined.
NODE_ENV only reflects the local dev server’s mode and is always 'development' once deployed, so the production rules would never apply.

You add generateStaticParams to /help/[slug] returning [{ slug: 'pricing' }, { slug: 'faq' }]. The page also has a branch that reads cookies(), but only when slug === 'admin-preview'. next build succeeds. What happens at runtime?

The build passes because no sample slug enters that branch, so the cookies() read is never validated — then a request to /help/admin-preview errors in production.
The build should have failed — cookies() is banned on any route that exports generateStaticParams.
The admin-preview branch is silently materialized as static HTML at build alongside pricing and faq.

Quiz complete

Score by topic