Adding View Transitions to a Next.js App

Wrap changing content in React's ViewTransition component to animate it across a Next.js navigation, with no extra config and no effect on the click itself.

7 min read

Next.js view transitions work by wrapping the content that changes between two routes in React's ViewTransition component, so the browser animates between the old and new version instead of swapping them instantly on navigation.

App.tsxApp.tsx
// app/blog/[slug]/page.tsx
import { ViewTransition } from "react";
 
export default function BlogPost({ title }: { title: string }) {
  return (
    <ViewTransition name="post-title">
      <h1>{title}</h1>
    </ViewTransition>
  );
}

Navigate from a list of posts to this page, and if the list also wraps its own title in a ViewTransition with the same name, the browser animates the title smoothly from its position in the list to its position on the post page instead of just replacing it outright.

Why no install step is needed

The App Router already runs on a React version that includes ViewTransition, so importing it directly from react works without adding a separate package or an experimental flag to the project's configuration. The component itself is still considered part of React's newer feature set, so treat it as evolving rather than as settled API surface, even though it works today with no setup and no separate opt-in step for a project already running on the App Router.

What actually needs to match

Both the outgoing and incoming element need the same name value for the browser to treat them as one continuous element to animate between. Without a matching name on both sides, the content just changes the normal way, with no animation at all, since the browser has nothing to connect the two elements across the navigation.

SituationResult
Same name on both routesBrowser animates between the two elements
Name only on one sideNo animation, content just changes
Browser lacks View Transitions API supportNo animation, navigation still works

Different animations for different navigations

Pass transitionTypes to a Link to tell a ViewTransition which kind of navigation just happened, such as moving forward through a list versus going back.

App.tsxApp.tsx
// app/nav.tsx
import Link from "next/link";
 
export default function PostLink({ slug }: { slug: string }) {
  return <Link href={`/blog/${slug}`} transitionTypes={["nav-forward"]}>Read post</Link>;
}

A view transition further down the tree can check for "nav-forward" and apply a different animation than it would for a back navigation, without the link itself needing any extra logic beyond this one prop. This is what lets a list-to-detail navigation feel different from a detail-to-list return, using the same underlying component on both routes.

For how a click reaches the new route before any animation runs, see Client-Side Navigation in Next.js: What Happens on a Link Click. For the rest of the props a link accepts alongside transitionTypes, read The Next.js Link Component: Props and Behavior Explained.

Rune AI

Rune AI

Key Insights

  • Import ViewTransition directly from react, no extra package or config needed.
  • Give matching elements on both routes the same name so the browser can animate between them.
  • Browsers without View Transitions API support still navigate correctly, just without the animation.
  • The transitionTypes prop on Link lets a ViewTransition apply a different animation per navigation.
  • This feature works independently of whether Cache Components is enabled.
RunePowered by Rune AI

Frequently Asked Questions

Do I need to install anything to use ViewTransition?

No. The App Router already runs on a React version that includes ViewTransition, so importing it from react works without installing a separate package.

What happens in a browser that does not support the View Transitions API?

The navigation still works normally. The content updates the same way it would otherwise, it just does not animate.

Do I need Cache Components enabled for this to work?

No. View transitions work independently of Cache Components and the caching model a project uses.

Conclusion

Wrapping changing content in React's ViewTransition component animates it across a Next.js navigation with no extra configuration. The animation only runs in browsers that support the View Transitions API, and navigation itself always works correctly even where it does not.