Last updated: First published:
Global Flow & Events
Astro’s view transition support is described in the Astro Docs↗. The following sections give additional details on process and events.
Astro’s view transition feature provides cross document transitions. It replace the full page load of normal browser navigation with a smooth animation while changing pages. Then it updates the browser history and the window’s scroll position. In the end, it works like normal navigation, but it feels more like the slick transitions within a single page app.
Astro’s <ViewTransitions />
use the View Transition API for browsers that support it natively. For other browsers, Astro provides a simulation.
Soft Load
When Astro introduced cross document view transitions, only Chrome supported real cross document view transitions and only after this experimental feature was explicitly enabled by the user. Support for cross document view transitions as defined in the Level 2 View Transition API is still in its infancy.
For browsers that do not have native support of the View Transition API, or only for Level 1, it is impossible to implement cross document view transitions without replacing the typical full page load. Instead a mechanism is required that allows to continue the execution of the code and to keep the state across the page switch. For Astro, this mechanism is also sometimes referred to as soft load of new contents. There are some fundamental differences between the soft load and the typical full page load.
The most important difference is that a full page load completely resets the state of the window object before it loads the new page. This includes resetting all variables, the DOM at window.document
, all scripts and the module loader. In contrast, Astro’s soft load retains all state and attempts to change it so it corresponds to the target state.
Triggers
There are four types of actions that trigger Astro’s View Transitions:
- Clicking on a link (HTML
<a>
Element, SVG Anchor<a>
and<map><area>
) - Submitting a
<form>
- Pressing a browsers buttons for history navigation, using according keyboard shortcuts, or calls to
history
functionsback()
,forward()
, orgo()
- Calling the
navigate()
function, which is provided byastro:transitions/client
Customization of the view transition is supported by Astro’s transition events and a view transition object with three promises that resolve or reject at different points during the transition. For details see the View Transition documentation↗ on MDN. Users can use the events and the promises to trigger custom code.
Processing Flow
Processing of the view transition flow begins with a preparation phase that by default loads the DOM of the target page. Then the actual view transition begins, which takes a screenshot of the current view (green line), swaps the current DOM with the contents of the loaded DOM and then starts the animations that remove the old image and in parallel bring in the new image (red line).
This is the behavior for browsers that have native view transition support. The startViewTransition(../flow-events/)
function and the view transition promises are part of the View Transition API.
For browsers that have no native support for view transitions, things happen slightly different. The exit animation to remove the old page happens on the green arrow, the enter animation to bring in the new image happens on the red arrow. The core functionality of the startViewTransition()
function and the view transition promises are provided by Astro.
In the completion phase, the newly added scripts are executed, the page title of the new route is announced for users of assistive technologies and some clean-up work is carried out at the end.
Step by Step
The single steps of the processing are as follows:
- Detect and cancel a previous view transition if it is still running
- Fallback to a full page load for a cross origin navigation (no CORS)
- Detection and handling of a same-page navigation, which does not trigger view transitions
- Trigger
astro:before-preparation
evente
- Fallback to a full page load if
e.defaultPrevented
is true - Start
e.loader()
and wait for end of asynchronous processing - Trigger
astro:after-preparation
event - Simulation only: start and wait for end of exit animations
- Native API: Call
startViewTransition()
with steps 9. - 12. as the update callback. Starts exit and enter animations in parallel once update is done. -
Trigger
astro:before-swap
evente
-
Run
e.swap()
-
Update browser history and scroll position
-
Trigger
astro:after-swap
event - Simulation only: start entry animations
- Start and await the loading (or error during loading) of new scripts
- Trigger
astro:page-load
event - Announce route to assistive technologies
- Wait for all animations to finish and clean up
For details about the customizable loader()
and swap()
functions see below and here
Events
The yellow blocks in the diagram above mark the positions in Astro’s navigation processing at which events are triggered. There are five events.
astro:before-preparation
andastro:after-preparation
at the beginning and end of the preparation phase.astro:before-swap
andastro:after-swap
at the beginning and end of the swap phase.astro:page-load
during the closing phase.
The astro:after-
events and the astro:page-load
event are standard Event
objects. Their main purpose is to allow the user code to react to the completion of a processing phase.
The astro:before-*
events provide navigation-specific properties
that show details of the processing. Some of these properties are even writable to give users control over the behavior of navigation processing.
All five events fire on window.document
.
astro:before-preparation
While the event listener code must run synchronously, the loader function will perform asynchronous actions.
The loader
property initially holds Astro’s built-in implementation for loading the contents of event.to
into event.newDocument
. An event listener might override the value of the loader
property to define a completely independent implementation.
Type | astro:before-preparation |
TypeScript Type | TransitionBeforePreparationEvent |
Cancelable | yes |
astro:before-swap
Most of the properties of the astro:before-swap
event are identical to those of the astro:before-preparation
event. The differences are:
direction
isreadonly
inastro:before-swap
formData
andloader
are not defined inastro:before-swap
- the
astro:before-swap
event offers two additional properties:
For documentation on startViewTransition
visit mdn↗. It is possible to override the built-in implementation of swap()
by assigning to the swap
property. Other than loader
, swap
does not support asynchronous actions. Browser implementations of view transition put a rather rigid timeout on the code that can run during swap. Long running code should be moved to the loader callback.
Type | astro:before-swap |
TypeScript Type | TransitionBeforeSwapEvent |
Cancelable | no |
Navigate()
The navigate function gives you programmatic access to view transitions. When you call it, it starts the processing flow described above.
The function accepts two parameters: the URL to be navigated to and an optional option parameter.
The function and its options are inspired by the Navigation API’s navigate()
↗.
history
controls whether thenavigate()
will change the browser’s history by callinghistory.pushState()
orhistory.replaceState()
. The values ofpush
andauto
are equivalent because the differences described asNotSupportedError
at https://developer.mozilla.org/en-US/docs/Web/API/Navigation/navigate#exceptions↗ can not be triggered with Astro.state
can be an arbitrary value that will be written into the browser’s history state.info
,formData
andsourceElement
: These are values that can be accessed in theastro:before-*
events.
The function returns a promise that fulfills when the new page got swapped in and the history entry got written. It does not wait for the animation of the view transition.