Skill

Animate React and Next.js View Transitions

Native React ViewTransition guide: shared elements, route transitions, list reorder, and transition types.

Works with reactnext.js

91
Spark score
out of 100
Updated 29 days ago
Version 14.1.0

Add to Favorites

Why it matters

Implement sophisticated UI animations in React and Next.js applications using native browser view transitions. This asset guides you through shared element animations, route transitions, and state changes for a seamless user experience.

Outcomes

What it gets done

01

Guide React and Next.js view transitions

02

Implement shared element animations

03

Control transition types with CSS

04

Ensure reduced-motion-safe UI state animation

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/ag-vercel-react-view-transitions | bash

Overview

React View Transitions

A React/Next.js native view-transitions guide covering the ViewTransition component, its four triggers, shared-element morphs, type-keyed animation, and list-identity patterns. Use when adding route, shared-element, list-reorder, or Suspense-reveal animations to a React or Next.js app using native browser view transitions.

What it does

React View Transitions animates between UI states using the browser's native document.startViewTransition: declare what with <ViewTransition>, trigger when with startTransition/useDeferredValue/Suspense, and control how with CSS classes, gracefully skipping animation on unsupported browsers.

When to use - and when NOT to

Use this when guiding React or Next.js view transitions, shared element animations, route transitions, transition types, or reduced-motion-safe UI state animation. Five patterns should be implemented in priority order wherever the app has a matching use case, not picked from selectively: shared element transitions (name-matched, "same thing going deeper"), Suspense reveals ("data loaded"), list identity via per-item key ("same items, new arrangement"), state-change enter/exit ("something appeared or disappeared"), and route-level layout transitions ("going to a new place"). Directional slides are reserved for hierarchical navigation and ordered sequences, where direction communicates position; lateral or unordered navigation like tab-to-tab should use a bare fade or default="none" instead, since a directional slide there falsely implies spatial depth.

Inputs and outputs

In Next.js, ViewTransition works out of the box via the App Router's bundled React canary - do not install react@canary separately. Outside Next.js, install react@canary react-dom@canary, since it isn't in stable React yet; browser support is Chromium 111+, Firefox 144+, and Safari 18.2+, with graceful degradation elsewhere. The <ViewTransition> component auto-assigns a view-transition-name and calls startViewTransition internally, never manually, and only fires enter/exit if it appears before any DOM nodes in its parent rather than being wrapped by one. Four triggers fire animations: enter (first inserted during a Transition), exit (first removed), update (a DOM mutation inside it, applying to the innermost nested VT), and share (a named VT unmounts while another with the same name mounts in the same Transition) - only startTransition, useDeferredValue, or Suspense activate these; a plain setState does not. Styling props accept "auto" for a browser cross-fade, "none" to disable, a custom class name, or a { [type]: value } map keyed by transition type set via addTransitionType, letting different VTs in the tree react differently to the same navigation - enter/exit need not be symmetric, for example fading in but sliding out. router.back() and the browser back/forward buttons do not trigger view transitions, since popstate is synchronous; use router.push() with an explicit URL instead.

Integrations

Shared-element morphs need a unique name per element, such as photo-${id}, since only one VT with a given name can be mounted at once - a component reused in both a modal and a page will break the morph unless the name is made conditional. When a list item itself contains a shared element, two nested <ViewTransition> boundaries are needed: an outer one keyed by item id for list reorder and enter, and an inner named one for the cross-route morph - missing either layer means that layer's animation silently doesn't happen. default="none" should be used liberally, since without it every VT fires the browser cross-fade on every transition, including background revalidations. A known limitation: when a parent VT exits, nested VTs inside it don't fire their own enter/exit, so per-item staggered animations during page navigation aren't currently possible. Companion reference files cover step-by-step implementation, ready-to-use CSS recipes including required reduced-motion CSS for accessibility, and Next.js-specific setup.

Who it's for

React and Next.js developers adding native browser view transitions for route changes, shared-element morphs, list reordering, or Suspense reveals, who need the placement, trigger, and type-mapping rules to get animations to actually fire rather than silently no-op.

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.