Home / Articles / Smooth app-like navigations with the View Transitions API in Next.js

This article is published in English.

Smooth app-like navigations with the View Transitions API in Next.js

Use the View Transitions API with Next.js navigations for shared-element motion without heavy animation libraries.

805 words

The View Transitions API lets browsers animate between DOM states with less custom animation plumbing. In Next.js App Router projects it pairs naturally with client navigations when you want shared-element continuity instead of hard cuts.

What it is

A browser feature that snapshots old and new states and interpolates between them. You opt in, name shared elements, and customize with CSS where needed.

function navigateWithTransition(callback: () => void) {
  if (!document.startViewTransition) {
    callback();
    return;
  }

  document.startViewTransition(() => {
    callback();
  });
}

Why Next.js fits

Client-side route transitions already replace large view trees. View Transitions give that replacement a visual language users associate with native apps.

Browser support and polyfills

Support is improving but not universal. Decide whether to progressive-enhance or polyfill; polyfills add weight and imperfect fidelity.

"use client";

import { useRouter } from "next/navigation";
export function TransitionLink() {
  const router = useRouter();
  function navigate() {
    if (!document.startViewTransition) {
      router.push("/dashboard");
      return;
    }
    document.startViewTransition(() => {
      router.push("/dashboard");
    });
  }
  return (
    <button onClick={navigate}>
      Dashboard
    </button>
  );
}

Integration patterns

Enable transitions on navigations, mark shared elements with stable names, and keep layouts from jumping with reserved space.

.product-image {
  view-transition-name: product-image;
}

Customizing motion

CSS view-transition pseudo-selectors let you tune duration and easing. Prefer subtle motion; long animations feel slower than they are.

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 350ms;
}

::view-transition-old(root) {
  animation: fade-out 350ms ease;
}
::view-transition-new(root) {
  animation: fade-in 350ms ease;
}

Glitches, streaming, performance

Avoid animating elements that stream in late or resize heavily. Test slow networks. Prefer transforming compositor-friendly properties. If streaming misaligned snapshots, delay the transition or limit it to static chrome.

Use View Transitions when navigation continuity matters and your audience’s browsers qualify. Skip them when information density updates faster than animation can help. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name. Keep fixtures green, measure each stage separately, and refuse to ship on vibes alone when the next release can reintroduce the same silent failure mode under a new name.