Astro View Transitions

[check: …]
📖 Full guide → 📖 ASTRO_VIEW_TRANSITIONS.md — the complete narrative, code samples, and verified sources. This page is its interactive companion.

The idea

Drop <ClientRouter /> in your <head> and Astro turns every in-site link into a single-page-app navigation with a morph animation — pair an element across two pages with transition:name and the browser animates it from old position/size to new.

⚠ Renamed in Astro 5.0: the component was <ViewTransitions /> through Astro 4.x. In Astro 5.0 it was renamed to <ClientRouter /> (import from astro:transitions) to clarify that it is a client-side router, not just a fade. Old tutorials still say ViewTransitions — that no longer exists in v5.

import { ClientRouter } from 'astro:transitions' transition:name → pairs elements A↔B transition:animate → fade | slide | none transition:persist → keep state alive powered by document.startViewTransition()

The transition demo — simulated A → B navigation

One .html can't change routes, so this swaps two page mockups inside the real document.startViewTransition() — exactly what <ClientRouter /> does on a route change. The "Penguins" card carries the paired name on both pages; watch it morph from small (list, page A) to large (detail, page B). In real Astro, transition:name="hero-card" compiles to the very view-transition-name: hero-card CSS used below.

API:   current page: A (/) — list   paired name: hero-card

What the router does on each click

  1. Click an <a> (or back/forward)
  2. Router fetches the next page
  3. Calls document.startViewTransition() — browser screenshots the old page
  4. Inside the callback: swap <head> + <body>
  5. transition:persist elements are moved old → new DOM
  6. Paired view-transition-name elements morph A → B
  7. New scripts run, astro:page-load fires

No support? <ClientRouter fallback="swap|none" /> degrades gracefully (default animate simulates the transition).

The three transition directives

This bundle is HOW Astro animates route changes: <ClientRouter /> + the transition:* directives, all riding the browser's View Transitions API. Cross-refs: 🔗 astro_routing_layouts (transitions fire on route change) · 🔗 astro_islands (persist keeps an island alive across pages).