diff --git a/packages/bridge/src/runtime/app.plugin.mjs b/packages/bridge/src/runtime/app.plugin.mjs index 522b5e0d03..5d58f11b85 100644 --- a/packages/bridge/src/runtime/app.plugin.mjs +++ b/packages/bridge/src/runtime/app.plugin.mjs @@ -5,6 +5,7 @@ import { setNuxtAppInstance } from '#app' // Reshape payload to match key `useLazyAsyncData` expects function proxiedState (state) { state._asyncData = state._asyncData || {} + state._errors = state._errors || {} return new Proxy(state, { get (target, prop) { if (prop === 'data') { @@ -39,7 +40,7 @@ export default (ctx, inject) => { globalName: 'nuxt', payload: proxiedState(process.client ? ctx.nuxtState : ctx.ssrContext.nuxt), _asyncDataPromises: [], - isHydrating: ctx.isHMR, + isHydrating: true, nuxt2Context: ctx } @@ -51,6 +52,10 @@ export default (ctx, inject) => { ctx.app.created = [ctx.app.created] } + if (!Array.isArray(ctx.app.mounted)) { + ctx.app.mounted = [ctx.app.mounted] + } + if (process.server) { nuxtApp.ssrContext = ctx.ssrContext } @@ -59,6 +64,8 @@ export default (ctx, inject) => { nuxtApp.vue2App = this }) + ctx.app.mounted.push(() => { nuxtApp.isHydrating = false }) + const proxiedApp = new Proxy(nuxtApp, { get (target, prop) { if (prop[0] === '$') { diff --git a/packages/nuxt3/src/app/composables/asyncData.ts b/packages/nuxt3/src/app/composables/asyncData.ts index a5d2c483e7..83292ac3ce 100644 --- a/packages/nuxt3/src/app/composables/asyncData.ts +++ b/packages/nuxt3/src/app/composables/asyncData.ts @@ -75,7 +75,7 @@ export function useAsyncData< const asyncData = { data: ref(nuxt.payload.data[key] ?? options.default()), pending: ref(true), - error: ref(null) + error: ref(nuxt.payload._errors[key] ?? null) } as AsyncData asyncData.refresh = (force?: boolean) => { @@ -84,7 +84,7 @@ export function useAsyncData< return nuxt._asyncDataPromises[key] } asyncData.pending.value = true - // TODO: Cancel previus promise + // TODO: Cancel previous promise // TODO: Handle immediate errors nuxt._asyncDataPromises[key] = Promise.resolve(handler(nuxt)) .then((result) => { @@ -104,13 +104,13 @@ export function useAsyncData< .finally(() => { asyncData.pending.value = false nuxt.payload.data[key] = asyncData.data.value + nuxt.payload._errors[key] = !!asyncData.error.value delete nuxt._asyncDataPromises[key] }) return nuxt._asyncDataPromises[key] } const fetchOnServer = options.server !== false && nuxt.payload.serverRendered - const clientOnly = options.server === false || !nuxt.payload.serverRendered // Server side if (process.server && fetchOnServer) { @@ -120,22 +120,16 @@ export function useAsyncData< // Client side if (process.client) { - // 1. Hydration (server: true): no fetch - if (nuxt.isHydrating && fetchOnServer) { + if (fetchOnServer && nuxt.isHydrating) { + // 1. Hydration (server: true): no fetch asyncData.pending.value = false - } - // 2. Initial load (server: false): fetch on mounted - if (instance && nuxt.isHydrating && clientOnly) { - // Fetch on mounted (initial load or lazy fetch) + } else if (instance && (nuxt.isHydrating || options.lazy)) { + // 2. Initial load (server: false): fetch on mounted + // 3. Navigation (lazy: true): fetch on mounted instance._nuxtOnBeforeMountCbs.push(asyncData.refresh) - } else if (!nuxt.isHydrating) { // Navigation - if (instance && options.lazy) { - // 3. Navigation (lazy: true): fetch on mounted - instance._nuxtOnBeforeMountCbs.push(asyncData.refresh) - } else { - // 4. Navigation (lazy: false) - or plugin usage: await fetch - asyncData.refresh() - } + } else { + // 4. Navigation (lazy: false) - or plugin usage: await fetch + asyncData.refresh() } } diff --git a/packages/nuxt3/src/app/nuxt.ts b/packages/nuxt3/src/app/nuxt.ts index e7899a131b..e30ea5a384 100644 --- a/packages/nuxt3/src/app/nuxt.ts +++ b/packages/nuxt3/src/app/nuxt.ts @@ -76,6 +76,7 @@ export function createNuxtApp (options: CreateOptions) { payload: reactive({ data: {}, state: {}, + _errors: {}, ...(process.client ? window.__NUXT__ : { serverRendered: true }) }), isHydrating: process.client,