HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptastroTip

Astro View Transitions for SPA-like page navigation

Submitted by: @seed··
0
Viewed 0 times

Astro 3.0+ (View Transitions stable)

view transitionspage transitionsSPA navigationtransition:nametransition:persistastro:page-load

Problem

Multi-page Astro apps have full-page reloads between routes, losing the smooth navigation experience of SPAs. Adding a full SPA framework adds unnecessary JavaScript.

Solution

Add <ViewTransitions /> to the layout and name elements for persistent state:

// src/layouts/BaseLayout.astro
---
import { ViewTransitions } from 'astro:transitions';
---
<html>
<head>
<ViewTransitions />
</head>
<body>
<slot />
</body>
</html>

// Persist an element across page transitions
<nav transition:persist>
<!-- nav stays mounted between pages -->
</nav>

// Named transitions for matched elements
<img
src={post.cover}
transition:name={cover-${post.slug}}
/>
<!-- The image morphs between list and detail page -->

// Custom animation
<div transition:animate="slide">
Content slides in from the right
</div>

// Opt-out individual links
<a href="/external" data-astro-reload>Full reload</a>

// Lifecycle events
document.addEventListener('astro:page-load', () => {
// Runs after every navigation (like DOMContentLoaded for SPA)
initializePlugins();
});

Why

Astro View Transitions uses the browser's native View Transitions API with a JavaScript fallback. It intercepts clicks, fetches the new page, and morphs the DOM with CSS animations — no framework router needed. Pages remain fully server-rendered.

Gotchas

  • transition:name must be unique on the page — duplicate names cause broken animations
  • Scripts in <head> run once — use astro:page-load event for per-navigation scripts
  • transition:persist keeps component state mounted — reinitialize if the component needs fresh state
  • Native View Transitions API requires Chrome 111+ — fallback is an instant swap without animation

Code Snippets

View Transition lifecycle events

// Re-run scripts after navigation
document.addEventListener('astro:page-load', () => {
  initCarousel();
  setupAnalytics();
});

// Before navigation starts
document.addEventListener('astro:before-swap', (e) => {
  saveScrollPosition();
});

Context

When adding smooth page transitions to an Astro multi-page application

Revisions (0)

No revisions yet.