Type something to search...
Next.js instant

Next.js instant

Prefetching promises fast navigations, but a prefetched route can still feel slow in practice if something inside it — an uncached fetch, a runtime API call outside a Suspense boundary — blocks the UI from actually updating the moment a user clicks a link. The instant route segment config is Next.js's mechanism for catching that gap automatically: you declare what you expect a segment's navigation behavior to be, and the framework actively validates your code against that expectation, surfacing exactly which component would violate it.

This is a Cache-Components-only feature, and one of the more actively-evolving corners of the App Router's configuration surface — worth reading carefully if you're adopting it, since several of its behaviors (validation levels, in particular) are explicitly still experimental.

Why This Exists

Next.js prefetches every in-app <Link> visible on the current page automatically. But prefetching alone doesn't guarantee an instant-feeling navigation — if the destination segment does client-side data fetching, or the server can only return a partially prerendered shell, the UI can still visibly wait after a click even though prefetching already ran. instant lets you assert, per segment, "navigating here should never block on external data" — and have Next.js actually check that assertion against your real code, rather than just hoping it holds.

Basic Usage

export const instant = true;

export default function Page() {
  return <div>...</div>;
}

The Three Accepted Values

  • true — opts the segment into validation at whatever level is configured globally (see the defaults section below). Under the framework's own defaults, this means validation runs in development only, surfacing errors in the dev overlay.
  • false — opts the segment out of validation entirely (see "Disabling instant" below).
  • An object, e.g. { level: 'warning' } — opts in with an explicit validation level, rather than inheriting the global default.

The level Option

export const instant = {
  level: "warning",
};

As of this writing, 'warning' is the only supported level — it validates in development only, surfacing errors in the dev overlay without affecting your production build at all. The docs explicitly flag that a build-time validation level is planned for the future; until that ships, there's genuinely no reason to specify level explicitly unless you're deliberately opting into an experimental validation mode, since 'warning' is already what you get by omitting it or using instant = true directly.

Disabling instant on a Segment

Setting false tells Next.js this particular layout or page is allowed to block during navigation — useful specifically for exempting an ancestor that can't realistically be instant, while still asserting that pages beneath it should be:

export const instant = false;
export const instant = true;

With this configuration, navigating from outside the tabs section into it is allowed to block at the shared layout — but navigating between tabs, once you're already inside, is validated for instant behavior. This is a genuinely useful pattern: you don't have to make an entire feature instant end-to-end to benefit from asserting that the parts of it that can be instant, are.

A detail worth internalizing to avoid over-applying false: you don't need to mark every ancestor of an instant page as false just because that ancestor happens to do something blocking. A higher-up instant = true doesn't force its descendants to validate — and leaving an ancestor's instant config entirely unset is perfectly fine. Reach for an explicit false only when you've configured a deeper page as instant and specifically need to exempt navigations that pass through a blocking ancestor on the way there.

Disabling Static Shell Validation Specifically

Beyond navigation-blocking validation, Cache Components separately validates that every page produces a genuinely non-empty static shell at prerender time. To opt a route out of that specific check, the highest instant config in the route's tree needs to be false — a false set higher in the tree takes precedence over any deeper true, specifically for this static-shell validation. Setting false on the root layout disables static shell validation app-wide, but the recommendation is to place it as low in the tree as actually necessary, so the rest of your app keeps benefiting from the check rather than losing it wholesale for a problem that's isolated to one section.

How Validation Actually Works

instant triggers validation at every shared layout boundary along the route, running during development on both page loads and HMR updates, with results surfaced directly in the dev error overlay. Each reported error identifies the specific component that would block navigation — and the fix is almost always one of two things: wrap the blocking data access in a <Suspense> boundary, or cache it with use cache so it stops being a request-time blocker in the first place.

Configuring Validation Defaults App-Wide

By default, Cache Components apps validate every Page and Default segment in development, at the 'warning' level — you don't have to opt individual segments in for baseline validation to happen. experimental.instantInsights.validationLevel in next.config.js tunes this app-wide behavior:

module.exports = {
  experimental: {
    instantInsights: {
      validationLevel: "warning",
    },
  },
};

Two supported levels currently exist:

  • 'warning' (the framework default) — every Page and Default segment is implicitly validated, dev-only.
  • 'manual-warning' — only segments with an explicit instant export get validated, also dev-only. This is the setting to reach for if you want opt-in-only validation rather than the framework's default of validating everything automatically.

Setting instant = false on a specific segment opts that segment out of validation regardless of the global default.

Two forward-compatibility notes worth flagging: the framework default may shift toward stricter validation in a future release — since this whole feature is still experimental, that kind of change isn't treated as a breaking one, so pin validationLevel explicitly if you need stable, predictable behavior across upgrades. And Next.js's own synthesized error routes (/_global-error, /_not-found) are excluded from implicit validation by default — if you want those specifically validated, you have to opt them in with an explicit instant export.

Inspecting Loading States Directly

With Cache Components enabled, the Navigation Inspector in Next.js DevTools lets you freeze a navigation mid-flight to actually see what the "instant" (or blocking) UI looks like before dynamic content streams in. Toggle on Pause on navigations, then:

  • Refresh the page to freeze the initial static shell before any dynamic data arrives.
  • Click a link to freeze the prefetched UI for the destination, before the navigation completes.

Click Resume to let the frozen navigation finish — the pause toggle stays active, so the next refresh or click pauses again until you turn it off. Checking both refreshes and link clicks matters, since first-visit and navigation loading states can genuinely differ.

Testing This in CI

@next/playwright exports an instant() helper specifically for asserting instant-navigation behavior in end-to-end tests — it holds back dynamic content while your test callback runs against the instant UI, letting you write a regression test that fails if a future change accidentally introduces a blocking dependency into a segment you've asserted should be instant.

import { instant } from "@next/playwright";

A Known Rough Edge: Shared Cookie Across Local Projects

The DevTools mechanism for freezing pages relies on a next-instant-navigation-testing cookie. Because cookies scope to domain, not port, running multiple local projects on localhost (the overwhelmingly common local dev setup) means this cookie is shared across all of them — switching between projects without clearing it, or without closing the Navigation Inspector panel first, can produce genuinely confusing cross-project state bleed. The docs flag this explicitly as a known issue slated for a fix once the feature stabilizes — until then, clear the cookie or close the panel deliberately when switching projects.

TypeScript

type InstantConfig =
  | true
  | false
  | {
      level?: "warning";
    };

export const instant: InstantConfig = true;

Version History

VersionChanges
v16.x.xinstant export introduced (Cache Components only)

Key Takeaways

AspectDetail
RequiresCache Components enabled — unavailable otherwise
Client ComponentsCannot be used — throws an error
trueValidates at the globally-configured level (default: dev-only warnings)
falseOpts out entirely — either navigation-blocking validation, or (set high enough in the tree) static-shell validation
Only supported level'warning' — build-time validation is planned but not yet available
Common fix for validation errorsWrap the blocking access in <Suspense>, or cache it with use cache
Testing@next/playwright's instant() helper for regression tests

instant turns "does this navigation feel fast" from a subjective impression into something Next.js can actually check for you at dev time — pinpointing exactly which component broke the promise, rather than leaving you to profile a sluggish navigation by hand. Given its experimental status, it's worth adopting deliberately on the routes where instant navigation is a genuine product requirement, rather than turning it on everywhere before its validation model has fully stabilized.

Tags :
Share :

Related Posts

Can Next.js Be Used with GraphQL?

Can Next.js Be Used with GraphQL?

Next.js and GraphQL are two powerful technologies that have gained significant traction in the web development community. Next.js, a React-based fram

Dive Deeper
How does Next.js differ from Create React App?

How does Next.js differ from Create React App?

In the world of modern web development, React.js has emerged as a dominant force due to its flexibility, performance, and extensive ecosystem. Two po

Dive Deeper
How does Next.js handle image optimization?

How does Next.js handle image optimization?

In modern web development, image optimization plays a critical role in enhancing user experience and improving site performance. Large, unoptimized i

Dive Deeper