diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 975f998ba2ebd..2a8147fbe3e55 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -465,20 +465,108 @@ 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:page-load` +## Lifecycle events -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`. +The `` router fires a number events on the `document` during navigation. These events provide hooks into the lifecycle of navigation, allowing you to do things like show indicators that a new page is loading, override default behavior, and restore state as navigation is completing. -The `` component fires this event both on initial page navigation (MPA) and any subsequent navigation, either forwards or backwards. +The navigation process involves a **preparation** phase, when new content is loaded; a **DOM swap** phase, where the old page's content is replaced by the new page's content; and a **completion** phase where scripts are executed, loading is reported as completed and clean-up work is carried out. -You can use this event to run code on every page navigation, or only once ever: +Astro's View Transition API lifecycle events in order are: +- [`astro:before-preparation`](#astrobefore-preparation) +- [`astro:after-preparation`](#astroafter-preparation) +- [`astro:before-swap`](#astrobefore-swap) +- [`astro:after-swap`](#astroafter-swap) +- [`astro:page-load`](#astropage-load) -```astro "{ once: true }" - +``` + +### `astro:after-preparation` + + + +An event that fires at the end of the preparation phase, after the new page's content has been loaded and parsed into a document. This event occurs before the view transitions phase. + +This example uses the `astro:before-preparation` event to start a loading indicator and the `astro:after-preparation` event to stop it: + +```astro + +``` +This is a simpler version of loading a spinner than the example shown above: if all of the listener's code can be executed synchronously, there is no need to hook into the loader's callback. + +### `astro:before-swap` + + + +An event that fires before the new document (which is populated during the preparation phase) replaces the current document. This event occurs inside of the view transition, where the user is still seeing a snapshot of the old page. + +This event can be used to make changes before the swap occurs. The `newDocument` property on the event represents the incoming document. Here is an example of ensuring the browser's light or dark mode preference in `localStorage` is carried over to the new page: + +```astro + +``` + +The `astro:before-swap` event can also be used to change the *implementation* of the swap. The default swap implementation diffs head content, moves __persistent__ elements from the old document to the `newDocument`, and then replaces the entire `body` with the body of the new document. + +At this point of the lifecycle, you could choose to define your own swap implementation, for example to diff the entire contents of the existing document (which some other routers do): + +```astro + ``` @@ -488,20 +576,30 @@ An event that fires immediately after the new page replaces the old page. You ca This event, when listened to on the **outgoing page**, is useful to pass along and restore any state on the DOM that needs to transfer over to the new page. -For example, if you are implementing dark mode support, this event can be used to restore state across page loads: +This is the latest point in the lifecyle where it is still safe to, for example, add a dark mode class name (``), though you may wish to do so in an earlier event. -```astro +The `astro:after-swap` event occurs immediately after the browser history has been updated and the scroll position has been set. +Therefore, one use of targeting this event is to override the default scroll restore for history navigation. The following example resets the horizontal and vertical scroll position to the top left corner of the page for each navigation. + +```js +document.addEventListener('astro:after-swap', + () => window.scrollTo({ left: 0, top: 0, behavior: 'instant' })) +``` + +### `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`. + +The `` component fires this event both on initial page navigation for a pre-rendered page and on any subsequent navigation, either forwards or backwards. + +You can use this event to run code on every page navigation, or only once ever: + +```astro "{ once: true }" ```