From 3e1fb24cee27daede685e394a76730ad7cea7e71 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Wed, 15 Nov 2023 11:42:14 -0500 Subject: [PATCH 01/15] VT event lifecycle docs --- .../docs/en/guides/view-transitions.mdx | 107 ++++++++++++++---- 1 file changed, 85 insertions(+), 22 deletions(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 975f998ba2ebd..6d1e6cca2f4b7 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -465,20 +465,79 @@ 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 to do things like showing 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. +### `astro:before-preparation` -You can use this event to run code on every page navigation, or only once ever: + -```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 the `newDocument` property. You can use this event to manipulate the state of the document before it is swapped with the existing document. + +Here's how you might ensure that a user's site theme (light and dark mode) preference carries over to the new page, when it is implemented as a localStorage feature: + +```astro + +``` + +### `astro:before-swap` + + + +An event that fires befores the new document, populated during the preparation phase, replaces the current document. This event occurs inside of the view transition, where the user is seeing a snapshot of the old page. + +This event can 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. + +If you wanted your own swap implementation, to for example diff the entire contents of the existing document (which some other routers do), this would be the event to do so. + +```astro + ``` @@ -488,20 +547,24 @@ 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: +Previously this event was used to implement dark mode. You could listen to the event and then add the dark mode class name to, for example: ``. This is still a valid way to do it, but it might be better to do so in an earlier event, like `astro:after-preparation` which occurs before the swap and before the view transition occurs. -```astro +As the `astro:after-swap` event occurs immediately before the view transition ends, it's a good time to stop any loading indicators that might be running. + +### `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 (MPA) and 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 }" ``` From 443205897ba60981feb74b5dd312282d1c8b75ba Mon Sep 17 00:00:00 2001 From: Sarah Rainsberger Date: Thu, 16 Nov 2023 19:25:21 +0000 Subject: [PATCH 02/15] sarah editing pass --- .../docs/en/guides/view-transitions.mdx | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 6d1e6cca2f4b7..fe49b233a9c2d 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -467,21 +467,32 @@ Module scripts are only ever executed once because the browser keeps track of wh ## Lifecycle events -The `` router fires a number events on the `document` during navigation. These events provide hooks into the lifecycle of navigation, allowing to do things like showing indicators that a new page is loading, override default behavior, and restore state as navigation is completing. +The `` router fires a number events on the `document` during navigation. These events provide hooks into the lifecycle of navigation, allowing to you do things like showing indicators that a new page is loading, override default behavior, and restore state as navigation is completing. + +The navigation phase 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 the new page is loaded, scripts are executed and clean-up work is carried out. + +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`) + +While some actions can be trigged during any event, some tasks can only be performed during a specific event for best results, such as displaying a loading spinner before preparation or overriding animation pairs before swapping content. ### `astro:before-preparation` -An event that fires at the beginning of the preparation phase, after navigation has started (for example, after the user has clicked a link), but before content is loaded. +An event that fires at the beginning of the preparation phase, after navigation has started (e.g. after the user has clicked a link), but before content is loaded. -This event is useful for a few use-cases: +This event is used: - To do something before loading has started, such as showing an a loading spinner. - To alter loading, such as loading content you've defined in a template rather than from the external URL. -- To change the `direction` of the navigation (which is usually either `forward` or `backward`) in order to do custom animation. +- To change the `direction` of the navigation (which is usually either `forward` or `backward`) for custom animation. -Here's an example of using the `astro:before-preparation` event to load a spinner before the content is loaded. +Here is an example of using the `astro:before-preparation` event to load a spinner before the content is loaded. ```js +``` + +### `astro:before-swap` + + + +An event that fires befores the new document, 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 ``` -### `astro:before-swap` - - -An event that fires befores the new document, 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 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. +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): From 428eee445f243d171983da56b714ddf7ee1c5514 Mon Sep 17 00:00:00 2001 From: Sarah Rainsberger Date: Mon, 20 Nov 2023 11:03:06 -0400 Subject: [PATCH 06/15] do we like this tip? --- src/content/docs/en/guides/view-transitions.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index c710f5ce25980..79137ae8c83d3 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -478,7 +478,11 @@ Astro's View Transition API lifecycle events in order are: - [`astro:after-swap`](#astroafter-swap) - [`astro:page-load`](#astropage-load) -While some actions can be trigged during any event, some tasks can only be performed during a specific event for best results, such as displaying a loading spinner before preparation or overriding animation pairs before swapping content. +:::tip +`before-` events allow you to influence and modify actions that are about to take place, and `after-` events are notifications that a phase is complete. +::: + +While some actions can be triggered during any event, some tasks can only be performed during a specific event for best results, such as displaying a loading spinner before preparation or overriding animation pairs before swapping content. ### `astro:before-preparation` From 21eaa4e4281fbbb3a719560b99424efd8c1c4fe2 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 20 Nov 2023 17:21:07 -0500 Subject: [PATCH 07/15] Update src/content/docs/en/guides/view-transitions.mdx Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com> --- src/content/docs/en/guides/view-transitions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 79137ae8c83d3..0372c5dca0c9d 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -469,7 +469,7 @@ Module scripts are only ever executed once because the browser keeps track of wh The `` router fires a number events on the `document` during navigation. These events provide hooks into the lifecycle of navigation, allowing to you do things like showing indicators that a new page is loading, override default behavior, and restore state as navigation is completing. -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 the new page is loaded, scripts are executed and clean-up work is carried out. +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. Astro's View Transition API lifecycle events in order are: - [`astro:before-preparation`](#astrobefore-preparation) From bceabc347135f407dd83b4d5109723b116ad0f44 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 20 Nov 2023 17:21:13 -0500 Subject: [PATCH 08/15] Update src/content/docs/en/guides/view-transitions.mdx Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com> --- src/content/docs/en/guides/view-transitions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 0372c5dca0c9d..101f73a02799b 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -467,7 +467,7 @@ Module scripts are only ever executed once because the browser keeps track of wh ## Lifecycle events -The `` router fires a number events on the `document` during navigation. These events provide hooks into the lifecycle of navigation, allowing to you do things like showing indicators that a new page is loading, override default behavior, and restore state as navigation is completing. +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 showing indicators that a new page is loading, override default behavior, and restore state as navigation is completing. 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. From 2fde0081f68efb7a237b21002f94512740e4f5f9 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 20 Nov 2023 17:21:24 -0500 Subject: [PATCH 09/15] Update src/content/docs/en/guides/view-transitions.mdx Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com> --- src/content/docs/en/guides/view-transitions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 101f73a02799b..1d07c6b4d14ff 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -496,7 +496,7 @@ This event is used: - To alter loading, such as loading content you've defined in a template rather than from the external URL. - To change the `direction` of the navigation (which is usually either `forward` or `backward`) for custom animation. -Here is an example of using the `astro:before-preparation` event to load a spinner before the content is loaded. +Here is an example of using the `astro:before-preparation` event to load a spinner before the content is loaded and stop it immediately after loading. Note that using the loader callback in this way allows asynchronous execution of code. ```js ``` - +Compared to the spinner example above, this example looks simpler: 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` From fc5cb2770a89bcbe036531e88c3f8e40397e6611 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 20 Nov 2023 17:21:39 -0500 Subject: [PATCH 11/15] Update src/content/docs/en/guides/view-transitions.mdx Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com> --- src/content/docs/en/guides/view-transitions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 3e65773598e2c..4f270faf4eb07 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -579,7 +579,7 @@ This event, when listened to on the **outgoing page**, is useful to pass along a 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. -As the `astro:after-swap` event occurs immediately before the view transition ends, it's a good time to stop any loading indicators that might be running. +The "astro:after-swap" event occurs immediately after the browser history has been updated and the scroll position has been set. ### `astro:page-load` From 6ad54c0a29b9c12ae5beca08ed1feedbaacbc84e Mon Sep 17 00:00:00 2001 From: Sarah Rainsberger Date: Tue, 21 Nov 2023 16:49:20 -0400 Subject: [PATCH 12/15] Sarah tiny language/formatting nits! --- src/content/docs/en/guides/view-transitions.mdx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 4f270faf4eb07..2c2f9ea17c958 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -467,7 +467,7 @@ Module scripts are only ever executed once because the browser keeps track of wh ## Lifecycle events -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 showing indicators that a new page is loading, override default behavior, and restore state as navigation is completing. +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 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. @@ -530,12 +530,13 @@ This example uses the `astro:before-preparation` event to start a loading indica }); ``` -Compared to the spinner example above, this example looks simpler: If all of the listener's code can be executed synchronously, there is no need to hook into the loader's callback. +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 befores the new document, 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. +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: @@ -555,8 +556,6 @@ This event can be used to make changes before the swap occurs. The `newDocument` ``` - - 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): From d91edb79b388906a2f8ce0e6d2f3505d7bfb4137 Mon Sep 17 00:00:00 2001 From: Sarah Rainsberger Date: Tue, 21 Nov 2023 19:30:49 -0400 Subject: [PATCH 13/15] add after-swap scroll example Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com> --- src/content/docs/en/guides/view-transitions.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 2c2f9ea17c958..9d4c6efb1bc83 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -579,6 +579,12 @@ This event, when listened to on the **outgoing page**, is useful to pass along a 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. The "astro:after-swap" event occurs immediately after the browser history has been updated and the scroll position has been set. +Therefore, it is now possible to override the default scroll restore for history navigation if desired. 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` From 39fbfd2a012130fab4097385d534cc17eabf9cb0 Mon Sep 17 00:00:00 2001 From: Sarah Rainsberger Date: Tue, 21 Nov 2023 19:32:22 -0400 Subject: [PATCH 14/15] light edit --- src/content/docs/en/guides/view-transitions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index 9d4c6efb1bc83..bfe6611782bf4 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -579,7 +579,7 @@ This event, when listened to on the **outgoing page**, is useful to pass along a 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. The "astro:after-swap" event occurs immediately after the browser history has been updated and the scroll position has been set. -Therefore, it is now possible to override the default scroll restore for history navigation if desired. The following example resets the horizontal and vertical scroll position to the top left corner of the page for each navigation. +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', From 752730564f199de4d23af01af869ea398c11a762 Mon Sep 17 00:00:00 2001 From: Sarah Rainsberger Date: Wed, 22 Nov 2023 09:22:27 -0400 Subject: [PATCH 15/15] fix quotes for formatting Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com> --- src/content/docs/en/guides/view-transitions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/en/guides/view-transitions.mdx b/src/content/docs/en/guides/view-transitions.mdx index bfe6611782bf4..2a8147fbe3e55 100644 --- a/src/content/docs/en/guides/view-transitions.mdx +++ b/src/content/docs/en/guides/view-transitions.mdx @@ -578,7 +578,7 @@ This event, when listened to on the **outgoing page**, is useful to pass along a 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. -The "astro:after-swap" event occurs immediately after the browser history has been updated and the scroll position has been set. +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