Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

View transitions

Normally, when you click a link, the browser wipes the page and draws a new one. View transitions make the change smooth: the old page fades out, the new one fades in, and shared elements, such as a post title, "fly" to their new place. In Astro 5 this is turned on by the ClientRouter component.

Turning it on

Add the component to the <head> of the layout src/layouts/BaseLayout.astro:

---
import { ClientRouter } from 'astro:transitions';
import '../styles/global.css';
---
 
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>{Astro.props.title} | Anna's blog</title>
    <ClientRouter />
  </head>
  <body>
    <slot />
  </body>
</html>

Follow the blog links: pages change smoothly, with no white flash. ClientRouter intercepts link clicks, loads the new page itself and swaps the content with an animation. The site remains a set of ordinary HTML pages.

A shared element

If an element has the same transition:name on two pages, the browser animates its movement. In the card src/components/PostCard.astro:

<h2 transition:name={`title-${id}`}>
  <a href={url}>{title}</a>
</h2>

And on the post page src/pages/posts/[id].astro:

<h1 transition:name={`title-${post.id}`}>{post.data.title}</h1>

The card needs one more prop for this, id={post.id}. Click a post in the list and the card title smoothly moves and grows into the post heading. The name must be unique on the page, which is why the post id is part of it.

Animation type

The transition:animate directive picks the element's animation:

ValueEffect
fadeFade, the default
slideSlide to the side
noneNo animation

For example, <main transition:animate="slide"> slides the main content during a transition.

Keeping an island alive

transition:persist keeps an element alive between pages. <AudioPlayer client:load transition:persist /> keeps playing music while the visitor browses the blog instead of starting over.

Scripts and transitions

With ClientRouter, module scripts run once, on the first load of the site. Code that must run on every page is attached to the astro:page-load event:

<script>
  document.addEventListener('astro:page-load', () => {
    console.log('Opened page', location.pathname);
  });
</script>

The message appears in the browser console after every transition.

Common mistake

After turning on ClientRouter, the "Copy link" button from the previous lesson works only on the first page opened. Its script ran once and found the buttons of that page. Move element lookup and handler setup inside astro:page-load.

Thanks for reading!

Donate to the site — we work hard for you.