Instant navigation

export const instant asks Next.js to verify that navigating into a segment paints immediately. It changes no rendering behaviour — it only surfaces the code that would make a navigation wait.

Validation runs in development and reports into the error overlay. The only level currently available is 'warning', so a violation never fails a build.

What to check

In dev. Run pnpm dev and open the blocking tab. The error overlay raises an insight naming the component that is not in the App Shell. The clean and deferred tabs raise nothing.

In a build. Run pnpm build && pnpm start and click between the tabs. Watch the dot next to the nav links — it is driven by useLinkStatus, so a dot that appears at all means that navigation had to wait.

Navigation Inspector. In dev, open Next.js DevTools → Navigation Inspector and enable Pause on navigations. Clicking a link then freezes the page at the prefetched UI, which is precisely what instant validates. Turn it off when you are done — it sets a cookie scoped to the whole domain, so it leaks across other projects on localhost.

Prefetching is build-only. Next.js does not prefetch in dev, so navigations never feel as instant there as they will under next start. Validation still reflects the production behaviour.

The four tabs

/instant/clean

validates clean
Renders a use cache scope on the probe-shell profile (stale 10m). A stale time of 5 minutes or more makes the content App-Shell eligible, so a prefetch already contains it and the navigation has nothing to wait for.

/instant/deferred

validates clean
Renders the same not-in-shell data as the blocking tab, but inside a <Suspense> boundary. The fallback is in the shell, so the navigation paints immediately and the content streams in after. This is the fix the insight on the blocking tab suggests.

/instant/blocking

raises an insight in dev
Renders a use cache scope on the probe-no-shell profile (stale 60s) with no boundary above it. A stale time under 5 minutes is prerendered but excluded from the App Shell — so it is not in the prefetch, and the navigation has to wait on the server. Legal, prerenderable, and still not instant, which is exactly the gap this config exists to find.

/instant/opted-out

not validated
export const instant = false. Declares that this segment is allowed to block, and opts it out of validation — including the static shell check. Useful during a migration; place it as low in the tree as possible, because a false higher up overrides any deeper true.

Why stale time decides this

The blocking and clean tabs differ in one number. probe-shell has a 10 minute stale time; probe-no-shell has 60 seconds. Anything under 5 minutes is kept out of the App Shell, because the shell is what gets prefetched and cached on the client — content that would expire before the user clicks is not worth shipping in it.

So “is this navigation instant?” reduces to “is this content in the App Shell, or behind a Suspense boundary?”. See /cache-life for the full set of thresholds.