From 7e375b5ed8000c9db2d383b3b6b858f254c19815 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 23 Jan 2024 12:31:39 +0000 Subject: [PATCH] fix(nuxt): stop tracking suspense when error hydrating page (#25389) --- packages/nuxt/src/app/components/nuxt-layout.ts | 8 ++++++-- packages/nuxt/src/app/components/nuxt-root.vue | 6 +++++- packages/nuxt/src/pages/runtime/page.ts | 11 ++++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/nuxt/src/app/components/nuxt-layout.ts b/packages/nuxt/src/app/components/nuxt-layout.ts index 0f470b5307..7509f2f9ff 100644 --- a/packages/nuxt/src/app/components/nuxt-layout.ts +++ b/packages/nuxt/src/app/components/nuxt-layout.ts @@ -5,7 +5,7 @@ import type { RouteLocationNormalizedLoaded } from 'vue-router' // eslint-disable-next-line import/no-restricted-paths import type { PageMeta } from '../../pages/runtime/composables' -import { useRoute } from '../composables/router' +import { useRoute, useRouter } from '../composables/router' import { useNuxtApp } from '../nuxt' import { _wrapIf } from './utils' import { LayoutMetaSymbol, PageRouteSymbol } from './injections' @@ -71,6 +71,10 @@ export default defineComponent({ context.expose({ layoutRef }) const done = nuxtApp.deferHydration() + if (import.meta.client && nuxtApp.isHydrating) { + const removeErrorHook = nuxtApp.hooks.hookOnce('app:error', done) + useRouter().beforeEach(removeErrorHook) + } if (import.meta.dev) { nuxtApp._isNuxtLayoutUsed = true @@ -97,7 +101,7 @@ export default defineComponent({ } } }) as unknown as DefineComponent<{ - name?: (unknown extends PageMeta['layout'] ? MaybeRef : PageMeta['layout']) | undefined; + name?: (unknown extends PageMeta['layout'] ? MaybeRef : PageMeta['layout']) | undefined }> const LayoutProvider = defineComponent({ diff --git a/packages/nuxt/src/app/components/nuxt-root.vue b/packages/nuxt/src/app/components/nuxt-root.vue index f1cc0c1885..cfbb1aaea9 100644 --- a/packages/nuxt/src/app/components/nuxt-root.vue +++ b/packages/nuxt/src/app/components/nuxt-root.vue @@ -20,7 +20,7 @@ import { defineAsyncComponent, onErrorCaptured, onServerPrefetch, provide } from 'vue' import { useNuxtApp } from '../nuxt' import { isNuxtError, showError, useError } from '../composables/error' -import { useRoute } from '../composables/router' +import { useRoute, useRouter } from '../composables/router' import { PageRouteSymbol } from '../components/injections' import AppComponent from '#build/app-component.mjs' import ErrorComponent from '#build/error-component.mjs' @@ -31,6 +31,10 @@ const IslandRenderer = import.meta.server const nuxtApp = useNuxtApp() const onResolve = nuxtApp.deferHydration() +if (import.meta.client && nuxtApp.isHydrating) { + const removeErrorHook = nuxtApp.hooks.hookOnce('app:error', onResolve) + useRouter().beforeEach(removeErrorHook) +} const url = import.meta.server ? nuxtApp.ssrContext.url : window.location.pathname const SingleRenderer = import.meta.test && import.meta.dev && import.meta.server && url.startsWith('/__nuxt_component_test__/') && defineAsyncComponent(() => import('#build/test-component-wrapper.mjs') diff --git a/packages/nuxt/src/pages/runtime/page.ts b/packages/nuxt/src/pages/runtime/page.ts index 19bbc795b4..0313fdacc2 100644 --- a/packages/nuxt/src/pages/runtime/page.ts +++ b/packages/nuxt/src/pages/runtime/page.ts @@ -9,6 +9,7 @@ import type { RouterViewSlotProps } from './utils' import { generateRouteKey, wrapInKeepAlive } from './utils' import { RouteProvider } from '#app/components/route-provider' import { useNuxtApp } from '#app/nuxt' +import { useRouter } from '#app/composables/router' import { _wrapIf } from '#app/components/utils' import { LayoutMetaSymbol, PageRouteSymbol } from '#app/components/injections' // @ts-expect-error virtual file @@ -49,6 +50,10 @@ export default defineComponent({ let vnode: VNode const done = nuxtApp.deferHydration() + if (import.meta.client && nuxtApp.isHydrating) { + const removeErrorHook = nuxtApp.hooks.hookOnce('app:error', done) + useRouter().beforeEach(removeErrorHook) + } if (props.pageKey) { watch(() => props.pageKey, (next, prev) => { @@ -151,12 +156,12 @@ function haveParentRoutesRendered (fork: RouteLocationNormalizedLoaded | null, n return newRoute.matched.slice(0, index) .some( (c, i) => c.components?.default !== fork.matched[i]?.components?.default) || - (Component && generateRouteKey({ route: newRoute, Component }) !== generateRouteKey({ route: fork, Component })) + (Component && generateRouteKey({ route: newRoute, Component }) !== generateRouteKey({ route: fork, Component })) } function hasChildrenRoutes (fork: RouteLocationNormalizedLoaded | null, newRoute: RouteLocationNormalizedLoaded, Component?: VNode) { if (!fork) { return false } const index = newRoute.matched.findIndex(m => m.components?.default === Component?.type) - return index < newRoute.matched.length -1 -} \ No newline at end of file + return index < newRoute.matched.length - 1 +}