乐闻世界logo
搜索文章和话题

How do Astro's View Transitions work? How do you implement smooth page transition effects?

2月21日 16:13

Astro's View Transitions is a powerful feature that enables smooth page switching experiences similar to Single Page Applications (SPAs) while maintaining the performance benefits of static sites.

Core Concepts:

View transitions use the browser's native View Transitions API to provide smooth visual transitions during page navigation.

Basic Usage:

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

Transition Types:

  1. Fade:

    astro
    <ViewTransitions transition="fade" />
  2. Slide:

    astro
    <ViewTransitions transition="slide" />
  3. None:

    astro
    <ViewTransitions transition="none" />

Custom Transitions:

astro
--- // src/layouts/Layout.astro import { ViewTransitions } from 'astro:transitions'; --- <html> <head> <title>My Website</title> <ViewTransitions /> <style is:global> ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.5s; } @keyframes custom-fade { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } ::view-transition-new(root) { animation: custom-fade 0.5s ease-out; } </style> </head> <body> <slot /> </body> </html>

Shared Element Transitions:

astro
--- // src/pages/index.astro import { transition } from 'astro:transitions'; --- <h1 transition:name="hero-title">Welcome to My Website</h1> <img src="/hero.jpg" alt="Hero Image" transition:name="hero-image" /> <a href="/about" transition:name="cta-button">Learn More</a>
astro
--- // src/pages/about.astro import { transition } from 'astro:transitions'; --- <h1 transition:name="hero-title">About Us</h1> <img src="/about.jpg" alt="About Image" transition:name="hero-image" /> <a href="/" transition:name="cta-button">Back to Home</a>

Programmatic Navigation:

astro
--- import { transition } from 'astro:transitions'; --- <button onClick={() => transition.navigate('/about')}> About Us </button> <a href="/contact" data-astro-transition="fade"> Contact Us </a>

Advanced Configuration:

astro
--- // src/layouts/Layout.astro import { ViewTransitions } from 'astro:transitions'; --- <html> <head> <title>My Website</title> <ViewTransitions /> </head> <body> <script> import { navigate } from 'astro:transitions/client'; // Listen to navigation events document.addEventListener('astro:page-load', () => { console.log('Page loaded'); }); document.addEventListener('astro:after-preparation', () => { console.log('Page preparation complete'); }); // Custom navigation function customNavigate(url) { navigate(url, { history: 'push', state: { customData: 'value' }, }); } </script> <slot /> </body> </html>

Conditional Transitions:

astro
--- // src/layouts/Layout.astro import { ViewTransitions } from 'astro:transitions'; --- <html> <head> <title>My Website</title> <ViewTransitions /> <script> // Apply transitions only to specific links document.querySelectorAll('a[href^="/blog/"]').forEach(link => { link.setAttribute('data-astro-transition', 'fade'); }); </script> </head> <body> <slot /> </body> </html>

Integration with Client Components:

jsx
// src/components/Navigation.jsx import { useNavigate } from 'astro:transitions/client'; export function Navigation() { const navigate = useNavigate(); return ( <nav> <button onClick={() => navigate('/')}>Home</button> <button onClick={() => navigate('/about')}>About</button> <button onClick={() => navigate('/contact')}>Contact</button> </nav> ); }

Performance Optimization:

  1. Prefetch Links:

    astro
    <a href="/about" data-astro-transition-prefetch> About Us </a>
  2. Disable Transitions for Specific Pages:

    astro
    --- // src/pages/no-transition.astro --- <script> // Disable view transitions document.documentElement.dataset.astroTransition = 'false'; </script> <h1>This page has no transition effects</h1>
  3. Optimize Image Loading:

    astro
    --- import { Image } from 'astro:assets'; import heroImage from '../assets/hero.jpg'; --- <Image src={heroImage} alt="Hero" transition:name="hero-image" loading="eager" />

Event Listeners:

astro
--- // src/layouts/Layout.astro import { ViewTransitions } from 'astro:transitions'; --- <html> <head> <title>My Website</title> <ViewTransitions /> </head> <body> <script> // Navigation starts document.addEventListener('astro:before-preparation', (ev) => { console.log('Preparing to navigate to:', ev.to.pathname); }); // Navigation preparation complete document.addEventListener('astro:after-preparation', () => { console.log('Navigation preparation complete'); }); // Page starts loading document.addEventListener('astro:before-swap', () => { console.log('Starting page swap'); }); // Page loaded document.addEventListener('astro:page-load', () => { console.log('Page loaded'); // Reinitialize client components initClientComponents(); }); // Navigation error document.addEventListener('astro:after-swap', (ev) => { if (ev.detail?.error) { console.error('Navigation error:', ev.detail.error); } }); </script> <slot /> </body> </html>

Best Practices:

  1. Add <ViewTransitions /> in layout components
  2. Use transition:name for key elements to implement shared element transitions
  3. Use data-astro-transition-prefetch to prefetch important links
  4. Listen to navigation events to handle client-side state
  5. Use different transition effects for different page types
  6. Consider user experience and don't overuse animations
  7. Simplify transitions on mobile devices

Compatibility:

View transitions require browser support for the View Transitions API. For unsupported browsers, Astro automatically falls back to normal page navigation.

Astro's view transitions provide SPA-like user experiences for static sites while maintaining the performance and SEO benefits of static sites.

标签:Astro