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:
| Value | Effect |
|---|---|
fade | Fade, the default |
slide | Slide to the side |
none | No 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.