Переходы между страницами
Обычно при клике по ссылке браузер стирает страницу и рисует новую. Переходы между страницами (view transitions) делают смену плавной: старая страница растворяется, новая проявляется, а общие элементы — например заголовок статьи — «перелетают» на новое место. В Astro 5 это включает компонент ClientRouter.
Включение
Добавьте компонент в <head> макета src/layouts/BaseLayout.astro:
---
import { ClientRouter } from 'astro:transitions';
import '../styles/global.css';
---
<html lang="ru">
<head>
<meta charset="utf-8" />
<title>{Astro.props.title} — Блог Анны</title>
<ClientRouter />
</head>
<body>
<slot />
</body>
</html>Переходите по ссылкам блога: страницы меняются плавно и без мигания белого экрана. ClientRouter перехватывает клики по ссылкам, загружает новую страницу сам и меняет содержимое с анимацией. Сайт при этом остаётся набором обычных HTML-страниц.
Общий элемент
Если у элемента на двух страницах одинаковое имя transition:name, браузер анимирует его перемещение. В карточке src/components/PostCard.astro:
<h2 transition:name={`title-${id}`}>
<a href={url}>{title}</a>
</h2>А на странице статьи src/pages/posts/[id].astro:
<h1 transition:name={`title-${post.id}`}>{post.data.title}</h1>В карточку для этого нужно передать ещё пропс id={post.id}. Нажмите на статью в списке — заголовок карточки плавно переедет и вырастет в заголовок статьи. Имя должно быть уникальным на странице, поэтому в него добавлен id статьи.
Вид анимации
Директива transition:animate выбирает анимацию элемента:
| Значение | Эффект |
|---|---|
fade | Растворение, по умолчанию |
slide | Сдвиг в сторону |
none | Без анимации |
Например, <main transition:animate="slide"> сдвигает основное содержимое при переходе.
Сохранение острова
transition:persist оставляет элемент живым между страницами. <AudioPlayer client:load transition:persist /> продолжит играть музыку, пока посетитель листает блог, а не начнёт заново.
Скрипты и переходы
С ClientRouter скрипты модулей выполняются один раз, при первой загрузке сайта. Код, который должен срабатывать на каждой странице, вешают на событие astro:page-load:
<script>
document.addEventListener('astro:page-load', () => {
console.log('Открыта страница', location.pathname);
});
</script>В консоли браузера сообщение появится после каждого перехода.
Частая ошибка
После включения ClientRouter кнопка «Скопировать ссылку» из прошлого урока работает только на первой открытой странице. Её скрипт выполнился один раз и нашёл кнопки той страницы. Переносите поиск элементов и навешивание обработчиков внутрь astro:page-load.