Page VTs, not layout VTs

A layout boundary around children silences each page's enter and exit.

Next.js docsnextjs.org
Layouts persist across navigations, so enter and exit never fire there.
Directional motionRead docs ↗

From vercel-react-view-transitions, nextjs.md.

Where the boundary lives

Go forward, then back.

In layout.tsxBad
layout: <ViewTransition>{children}
In each page.tsxGood
page: <DirectionalTransition>
// app/layout.tsx: no ViewTransition around children
export default function Layout({ children }) {
  return <main>{children}</main>;
}

// app/docs/page.tsx
export default function Page() {
  return (
    <DirectionalTransition>
      <Docs />
      <Link href="/docs/setup" transitionTypes={['nav-forward']}>Setup →</Link>
    </DirectionalTransition>
  );
}

Why it matters, pros and cons

Why it matters

The layout persists, so its boundary never enters or exits. Each page boundary inside it mounts as one unit with it, and nested boundaries skip their own enter and exit.

Pros

  • Each page owns its direction.
  • Layout chrome keeps its state across routes.
  • transitionTypes on Link works in Server Components.

Cons

  • Every page repeats the wrapper; extract one component.
  • transitionTypes needs Next.js 16.2+.
  • Test in a production build: dev skips prefetch.