View transitions enable SPA-style navigation between pages using Astro’s native ClientRouter component. When enabled, page navigations use smooth cross-fade animations instead of full browser refreshes.
Who this is for
- Implementors enabling view transitions for a site
- Developers understanding the lifecycle implications for interactive components and custom scripts
Enabling view transitions
View transitions are disabled by default to preserve the zero-JS baseline. Enable them in src/site/config/site.ts:
export const siteConfig: SiteConfig = {
...DEFAULT_SITE_CONFIG,
viewTransitions: {
enabled: true,
},
};
When enabled, the ClientRouter component is added to the document head on every page. This activates client-side routing — link clicks fetch the destination page and swap the DOM with a cross-fade animation instead of performing a full page load.
Per-page opt-out
Individual pages can opt out of view transitions by setting viewTransitions: false in frontmatter:
---
title: My Page
viewTransitions: false
---
When a page opts out:
- The page renders without
ClientRouter, so outbound navigation from that page uses standard full-page loads - Inbound navigation to that page from a view-transitions-enabled page also falls back to a full-page load (Astro detects the destination lacks
ClientRouter)
Reduced motion
When prefers-reduced-motion: reduce is active, transition animations are automatically suppressed by the existing global CSS rule. Pages swap instantly without animation, but client-side routing remains functional — users still get fast SPA navigation without the motion.
Component lifecycle compatibility
Interactive components are SPA-aware. When view transitions are enabled:
- Components re-initialize on every SPA navigation via
astro:page-load WeakMapguards prevent double-initialization on persisted elements- Components with custom observers (Header, TocAside) clean up via
astro:before-swapusingAbortController
No additional configuration is needed for interactive components to work with view transitions.
Animation directive extension points
Core components ship with default cross-fade transitions. Site owners can enhance transitions on their own pages and components using Astro’s animation directives:
transition:name
Gives an element a stable identity across pages so the browser can morph it during the transition:
<!-- Page A -->
<img transition:name="hero" src="/hero-a.jpg" />
<!-- Page B -->
<img transition:name="hero" src="/hero-b.jpg" />
The browser animates the element from its position on page A to its position on page B.
transition:animate
Controls the animation type for a specific element. Built-in options: fade (default), slide, none.
<div transition:animate="slide">Slides in from the side during transition</div>
transition:persist
Keeps an element alive across navigations without re-rendering. Useful for media players or other stateful elements:
<video transition:persist src="/background.mp4" autoplay></video>
Note: the core theme does not use transition:persist — interactive components use full re-initialization via astro:page-load instead, which provides a simpler and more predictable lifecycle model.
For the full directive reference, see the Astro View Transitions documentation (external link).