AgentStack
SKILL verified MIT Self-run

Vercel React View Transitions

skill-ariadoss-superskills-react-view-transitions · by ariadoss

Guide for implementing smooth, native-feeling animations using React's View Transition API (`<ViewTransition>` component, `addTransitionType`, and CSS view transition pseudo-elements). Use this skill whenever the user wants to add page transitions, animate route changes, create shared element animations, animate enter/exit of components, animate list reorder, implement directional (forward/back)…

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-ariadoss-superskills-react-view-transitions

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README — it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-ariadoss-superskills-react-view-transitions)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
today

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Vercel React View Transitions? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

React View Transitions

Animate between UI states using the browser's native document.startViewTransition. Declare what with `, trigger *when* with startTransition / useDeferredValue / Suspense`, control how with CSS classes. Unsupported browsers skip animations gracefully.

When to Animate

Every `` should communicate a spatial relationship or continuity. If you can't articulate what it communicates, don't add it.

Implement all applicable patterns from this list, in this order:

| Priority | Pattern | What it communicates | |----------|---------|---------------------| | 1 | Shared element (name) | "Same thing — going deeper" | | 2 | Suspense reveal | "Data loaded" | | 3 | List identity (per-item key) | "Same items, new arrangement" | | 4 | State change (enter/exit) | "Something appeared/disappeared" | | 5 | Route change (layout-level) | "Going to a new place" |

This is an implementation order, not a "pick one" list. Implement every pattern that fits the app. Only skip a pattern if the app has no use case for it.

Choosing Animation Style

| Context | Animation | Why | |---------|-----------|-----| | Hierarchical navigation (list → detail) | Type-keyed nav-forward / nav-back | Communicates spatial depth | | Lateral navigation (tab-to-tab) | Bare ` (fade) or default="none" | No depth to communicate | | Suspense reveal | enter/exit string props | Content arriving | | Revalidation / background refresh | default="none"` | Silent — no animation needed |

Reserve directional slides for hierarchical navigation (list → detail) and ordered sequences (prev/next photo, carousel, paginated results). For ordered sequences, the direction communicates position: "next" slides from right, "previous" from left. Lateral/unordered navigation (tab-to-tab) should not use directional slides — it falsely implies spatial depth.


Availability

  • Next.js: Do not install react@canary — the App Router already bundles React canary internally. ViewTransition works out of the box. npm ls react may show a stable-looking version; this is expected.
  • Without Next.js: Install react@canary react-dom@canary (ViewTransition is not in stable React).
  • Browser support: Chromium 111+, Firefox 144+, Safari 18.2+. Graceful degradation on unsupported browsers.

Core Concepts

The `` Component

import { ViewTransition } from 'react';

  

React auto-assigns a unique view-transition-name and calls document.startViewTransition behind the scenes. Never call startViewTransition yourself.

Animation Triggers

| Trigger | When it fires | |---------|--------------| | enter | ` first inserted during a Transition | | **exit** | first removed during a Transition | | **update** | DOM mutations inside a . With nested VTs, mutation applies to the innermost one | | **share** | Named VT unmounts and another with same name` mounts in the same Transition |

Only startTransition, useDeferredValue, or Suspense activate VTs. Regular setState does not animate.

Critical Placement Rule

`` only activates enter/exit if it appears before any DOM nodes:

// Works

  Content

// Broken — div wraps the VT, suppressing enter/exit

  
    Content
  

Styling with View Transition Classes

Props

Values: "auto" (browser cross-fade), "none" (disabled), "class-name" (custom CSS), or { [type]: value } for type-specific animations.

If default is "none", all triggers are off unless explicitly listed.

CSS Pseudo-Elements

  • ::view-transition-old(.class) — outgoing snapshot
  • ::view-transition-new(.class) — incoming snapshot
  • ::view-transition-group(.class) — container
  • ::view-transition-image-pair(.class) — old + new pair

Transition Types

Tag transitions with addTransitionType so VTs can pick different animations based on context. Call it multiple times to stack types — different VTs in the tree react to different types:

startTransition(() => {
  addTransitionType('nav-forward');
  addTransitionType('select-item');
  router.push('/detail/1');
});

Pass an object to map types to CSS classes. Works on enter, exit, and share:


  

TypeScript: ViewTransitionClassPerType requires a default key in the object.

For apps with multiple pages, extract the type-keyed VT into a reusable wrapper:

export function DirectionalTransition({ children }: { children: React.ReactNode }) {
  return (
    
      {children}
    
  );
}

router.back() and Browser Back Button

router.back() and the browser's back/forward buttons do not trigger view transitions (popstate is synchronous, incompatible with startViewTransition). Use router.push() with an explicit URL instead.


Shared Element Transitions

Same name on two VTs — one unmounting, one mounting — creates a shared element morph:


   startTransition(() => onSelect())} />

// On the other view — same name

  
  • Only one VT with a given name can be mounted at a time — use unique names (photo-${id}).
  • share takes precedence over enter/exit. When no matching pair forms, enter/exit fires instead.
  • Never use a fade-out exit on pages with shared morphs — use a directional slide instead.

Common Patterns

Enter/Exit

{show && (
  
)}

List Reorder

{items.map(item => (
  
))}

Trigger inside startTransition. Avoid wrapper ``s between list and VT.

Composing Shared Elements with List Identity

{items.map(item => (
                                        {/* list identity */}
    
         {/* shared element */}
        
      
      {item.name}
    
  
))}

Force Re-Enter with key


  

Caution: If wrapping `, changing key` remounts the boundary and refetches.

Suspense Fallback to Content

Simple cross-fade:


  }>

Directional reveal:

}>
  

How Multiple VTs Interact

Every VT matching the trigger fires simultaneously in a single document.startViewTransition. VTs in different transitions (navigation vs later Suspense resolve) don't compete.

Use default="none" Liberally

Without it, every VT fires the browser cross-fade on every transition — Suspense resolves, useDeferredValue updates, background revalidations. Always use default="none" and explicitly enable only desired triggers.

Two Patterns Coexist

Pattern A — Directional slides: Type-keyed VT on each page, fires during navigation. Pattern B — Suspense reveals: Simple string props, fires when data loads (no type).

They coexist because they fire at different moments. default="none" on both prevents cross-interference. Always pair enter with exit. Place directional VTs in page components, not layouts.

Nested VT Limitation

When a parent VT exits, nested VTs inside it do not fire their own enter/exit — only the outermost VT animates. Per-item staggered animations during page navigation are not possible today.


Accessibility

Always add the reduced motion CSS to your global stylesheet:

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.