Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

View transitions 3.0 changes #4320

Merged
merged 21 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 44 additions & 32 deletions src/content/docs/en/guides/view-transitions.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: View Transitions (Experimental)
title: View Transitions
description: >-
How to enable experimental support for view transitions in your Astro site.
Enable seamless navigation between pages in Astro, with view transitions.
i18nReady: true
---

import Since from '~/components/Since.astro'

Support for **opt-in, per-page, view transitions** in Astro projects can be enabled behind an experimental flag. View transitions update your page content without the browser's normal, full-page navigation refresh and provide seamless animations between pages.
Astro supports **opt-in, per-page, view transitions** with just a few simple APIs. View transitions update your page content without the browser's normal, full-page navigation refresh and provide seamless animations between pages.

Astro provides a `<ViewTransitions />` routing component that can be added to a single page's `<head>` to control page transitions as you navigate away to another page, an effect traditionally only possible with client-side routing. Add this component to a reusable `.astro` component, such as a common head or layout, for animated page transitions across your entire site (SPA mode).

Expand All @@ -18,30 +18,6 @@ Astro's view transitions support is powered by the new [View Transitions](https:
- The ability to fully [customize all aspects of transition animation](#customizing-animations), and build your own animations.
- [Control over fallback behavior](#fallback-control) for browsers that do not yet support the View Transition APIs.

:::caution
View transitions is an experimental feature enabled in Astro 2.9. The API is subject to change before it is marked as stable.
:::

## Enabling View Transitions in your Project

You can enable support for animated page transitions through the experimental `viewTransitions` flag in your Astro config:

```js title="astro.config.mjs" ins={4-6}
import { defineConfig } from 'astro/config';

export default defineConfig({
experimental: {
viewTransitions: true
}
});
```

:::note
Enabling view transitions support does not automatically convert your entire site into a SPA (Single-page App). By default, every page will still use regular, full-page, browser navigation.

Add page transitions in Astro with the `<ViewTransitions />` routing component on a per-page basis, or site-wide.
:::

## Full site view transitions (SPA mode)

Import and add the `<ViewTransitions />` component to your common `<head>` or shared layout component. Astro will create default page animations based on the similiarities between the old and new page, and will also provide fallback behavior for unsupported browsers.
Expand Down Expand Up @@ -244,9 +220,33 @@ import { ViewTransitions } from 'astro:transitions';
```

:::note[known limitations]
The `morph` animation cannot be simulated in traditional CSS. So any element using this animation will not be animated.
The `morph` animation is not simulated by Astro. So any element using this animation will not be animated.
:::

## Navigation steps

When using the `<ViewTransitions />` router, the following steps are performed as part of navigation:

1. The user triggers navigation by either:
- Click a `<a>` to another page in your site.
- Clicking the back button.
- Clicking the forward button.
2. The router starts fetching the next page.
3. The router adds the `data-astro-transition` attribute to the HTML element with a value of `'forward'` or `'back'` depending on whether it is back navigation or not.
4. The router calls `document.startViewTransition`. This triggers the browsers own [view transition process](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API#the_view_transition_process). Importantly the browser screenshots the current state of the page.
5. Inside the `startViewTransition` callback, the router performs a __swap__.
1. The contents of the `<head>` are swapped out.
- Stylesheet DOM nodes are left in if they exist on the new page, to prevent FOUC.
- Scripts are left in if they exist on the new page.
- Any other head elements with `transition:persist` are left in if there is a corresponding element in the new page.
2. The `<body>` is completely replaced with the new page's body.
3. Elements marked `transition:persist` are moved over to the new DOM if they exist on the new page.
4. Scroll position is restored if necessary.
5. The `astro:after-swap` event is triggered on the `document`. This is the end of the __swap__ process.
6. The router waits for any new stylesheets to load before resolving the transition.
7. The router executes any new scripts added to the page.
8. The `astro:page-load` event fires. This is the end of the navigation process.

## Script behavior during page navigation

When navigating between pages with the `<ViewTransitions />` component, scripts are run in sequential order to match browser behavior.
Expand All @@ -263,7 +263,7 @@ If you have code that sets up global state, this state will need to take into ac

Module scripts are only ever executed once because the browser keeps track of which modules are already loaded. For these scripts, you do not need to worry about re-execution.

### `astro:load`
### `astro:page-load`

An event that fires at the end of page navigation, after the new page is visible to the user and blocking styles and scripts are loaded. You can listen to this event on the `document`.

Expand All @@ -273,14 +273,14 @@ You can use this event to run code on every page navigation, or only once ever:

```astro "{ once: true }"
<script>
document.addEventListener('astro:load', () => {
document.addEventListener('astro:page-load', () => {
// This only runs once.
setupStuff();
}, { once: true });
</script>
```

### `astro:beforeload`
### `astro:after-swap`

An event that fires immediately after the new page replaces the old page. You can listen to this event on the `document`.

Expand All @@ -299,10 +299,22 @@ For example, if you are implementing dark mode support, this event can be used t
// Runs on initial navigation
setDarkMode();
// Runs on view transitions navigation
document.addEventListener('astro:beforeload', setDarkMode);
document.addEventListener('astro:after-swap', setDarkMode);
</script>
```

## `prefers-reduced-motion`

Astro's `<ViewTransitions />` component includes a CSS media query that disables *all* view transition animations, including fallback animation, whenever the [`prefer-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion) setting is detected. Instead, the browser will simply swap the DOM elements without an animation.

## Preventing client-side navigation

Once you have enabled client-side routing on a page by adding the `<ViewTransitions />` component, every anchor on the page that links to another page on your site will be navigated via client-side routing. There are some cases where you might want to not navigate via CSR. One example is if it he link is to any non-page, such as a PDF within your `public/` folder. Or an API route that produces an image.

In these cases you can opt-out of client-side routing on a per-link basis using the `data-astro-reload` attribute like so:

```html
<a href="/quarterly-earnings.pdf" data-astro-reload>
```

These links will be ignored by the router and a full page navigation will occur.
2 changes: 1 addition & 1 deletion src/i18n/en/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default [
{ text: 'Middleware', slug: 'guides/middleware', key: 'guides/middleware' },
{ text: 'Testing', slug: 'guides/testing', key: 'guides/testing' },
{
text: 'View Transitions (Experimental)',
text: 'View Transitions',
slug: 'guides/view-transitions',
key: 'guides/view-transitions',
},
Expand Down