Articles

Use React <ViewTransition /> to Smoothly Transition Images and Titles

Kent C. Dodds
Kent C. Dodds

Smooth Page Transitions with React's ViewTransition Component

React 19's ViewTransition component makes it easy to create smooth, animated transitions between pages. Wrap elements with the same name on different pages and React handles the rest.

Remember when clicking between pages meant an abrupt jump? Users expect smooth transitions now, especially after years of polished mobile apps. React's new <ViewTransition /> component (available in React 19 Canary) makes it easy to create those smooth, animated transitions between pages.

What is ViewTransition?

<ViewTransition /> is React's componentized way to use the platform's View Transition API. It lets you animate elements as they move from one page to another, creating that polished, app-like feel users expect.

The concept is simple: wrap elements you want to transition with <ViewTransition /> and give them the same name prop. When React navigates between pages, it automatically animates elements with matching names.

A Practical Example

Let's say you have a movie catalog. When users click a movie card, they navigate to the details page. Wouldn't it be nice if the poster image smoothly transitioned from the card to the details page? That's exactly what ViewTransition does.

Here's the movie card component:


<ViewTransition name={`movie-poster-${movie.id}`}>
<img
src={movie.poster}
alt={`${movie.title} poster`}
className="mb-4 h-64 w-full rounded-lg object-cover"
/>
</ViewTransition>

And here's the same element on the details page:


<ViewTransition name={`movie-poster-${movie.id}`}>
<img
src={movie.poster}
alt={`${movie.title} poster`}
className="h-96 w-full rounded-lg object-cover"
/>
</ViewTransition>

Notice both use the same name prop: movie-poster-${movie.id}. This tells React these are the same element transitioning between pages. When you navigate, React automatically creates a smooth fade transition between them.

Multiple Elements

You can transition multiple elements at once. Let's also transition the title:


<ViewTransition name={`movie-title-${movie.id}`}>
<h3 className="rr-heading text-lg font-semibold">{movie.title}</h3>
</ViewTransition>

And on the details page:


<ViewTransition name={`movie-title-${movie.id}`}>
<h1 className="rr-heading mb-4 text-3xl font-bold">{movie.title}</h1>
</ViewTransition>

Now both the poster and title smoothly transition when navigating between pages. The browser handles the animation automatically with a default cross-fade, but you can customize it with CSS if you want.

Important Details

Unique names are required: Each <ViewTransition /> with the same name must be unique across your entire app. That's why we use movie-poster-${movie.id} instead of just "movie-poster". If two components with the same name are mounted simultaneously, React will throw an error.

Works with Transitions: ViewTransition only activates when wrapped in a startTransition call. Most routers (like React Router) handle this automatically, but if you're managing navigation manually, make sure to use startTransition.

Placement matters: The <ViewTransition /> component must wrap DOM nodes directly. It can't be placed after other DOM elements in the same parent.

Customization

By default, ViewTransition uses a smooth cross-fade animation. But you can customize it with CSS using view transition pseudo-elements:


::view-transition-old(movie-poster-1) {
animation-duration: 500ms;
}
::view-transition-new(movie-poster-1) {
animation-duration: 500ms;
}

You can create slide animations, scale effects, or any other CSS animation you can imagine. The platform's View Transition API is powerful, and React's component makes it accessible.

Learn More

ViewTransition is a great example of React making platform APIs more ergonomic. To dive deeper:

Give ViewTransition a try in your next project. Your users will notice the difference!

Get my free 7-part email course on React!

Delivered straight to your inbox.