diff --git a/docs/3.api/6.advanced/1.hooks.md b/docs/3.api/6.advanced/1.hooks.md index 35520e27c3..62da74b717 100644 --- a/docs/3.api/6.advanced/1.hooks.md +++ b/docs/3.api/6.advanced/1.hooks.md @@ -28,6 +28,7 @@ Hook | Arguments | Environment | Description `page:loading:start` | - | Client | Called when the `setup()` of the new page is running. `page:loading:end` | - | Client | Called after `page:finish` `page:transition:finish`| `pageComponent?` | Client | After page transition [onAfterLeave](https://vuejs.org/guide/built-ins/transition.html#javascript-hooks) event. +`page:view-transition:start` | `transition` | Client | Called after `document.startViewTransition` is called when [experimental viewTransition support is enabled](https://nuxt.com/docs/getting-started/transitions#view-transitions-api-experimental). ## Nuxt Hooks (build time) diff --git a/packages/nuxt/src/app/nuxt.ts b/packages/nuxt/src/app/nuxt.ts index bbdeb499d7..ce515d6a8b 100644 --- a/packages/nuxt/src/app/nuxt.ts +++ b/packages/nuxt/src/app/nuxt.ts @@ -18,6 +18,7 @@ import type { NuxtError } from '../app/composables/error' import type { AsyncDataRequestStatus } from '../app/composables/asyncData' import type { NuxtAppManifestMeta } from '../app/composables/manifest' import type { LoadingIndicator } from '../app/composables/loading-indicator' +import type { ViewTransition } from './plugins/view-transitions.client' import type { NuxtAppLiterals } from '#app' @@ -45,6 +46,7 @@ export interface RuntimeNuxtHooks { 'page:finish': (Component?: VNode) => HookResult 'page:transition:start': () => HookResult 'page:transition:finish': (Component?: VNode) => HookResult + 'page:view-transition:start': (transition: ViewTransition) => HookResult 'page:loading:start': () => HookResult 'page:loading:end': () => HookResult 'vue:setup': () => void diff --git a/packages/nuxt/src/app/plugins/view-transitions.client.ts b/packages/nuxt/src/app/plugins/view-transitions.client.ts index bb3a696d2d..e23dc02a04 100644 --- a/packages/nuxt/src/app/plugins/view-transitions.client.ts +++ b/packages/nuxt/src/app/plugins/view-transitions.client.ts @@ -14,7 +14,7 @@ export default defineNuxtPlugin((nuxtApp) => { const router = useRouter() - router.beforeResolve((to, from) => { + router.beforeResolve(async (to, from) => { const viewTransitionMode = to.meta.viewTransition ?? defaultViewTransition const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches const prefersNoTransition = prefersReducedMotion && viewTransitionMode !== 'always' @@ -41,6 +41,8 @@ export default defineNuxtPlugin((nuxtApp) => { finishTransition = undefined }) + await nuxtApp.callHook('page:view-transition:start', transition) + return ready }) @@ -55,12 +57,14 @@ export default defineNuxtPlugin((nuxtApp) => { }) }) +export interface ViewTransition { + ready: Promise + finished: Promise + updateCallbackDone: Promise +} + declare global { interface Document { - startViewTransition?: (callback: () => Promise | void) => { - finished: Promise - updateCallbackDone: Promise - ready: Promise - } + startViewTransition?: (callback: () => Promise | void) => ViewTransition } }