mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
fix(nuxt): skip vue render when redirecting (#21412)
This commit is contained in:
parent
6d62b65f97
commit
7710ed30fa
@ -118,7 +118,7 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
|
|||||||
const fullPath = typeof to === 'string' || isExternal ? toPath : router.resolve(to).fullPath || '/'
|
const fullPath = typeof to === 'string' || isExternal ? toPath : router.resolve(to).fullPath || '/'
|
||||||
const location = isExternal ? toPath : joinURL(useRuntimeConfig().app.baseURL, fullPath)
|
const location = isExternal ? toPath : joinURL(useRuntimeConfig().app.baseURL, fullPath)
|
||||||
|
|
||||||
async function redirect () {
|
async function redirect (response: any) {
|
||||||
// TODO: consider deprecating in favour of `app:rendered` and removing
|
// TODO: consider deprecating in favour of `app:rendered` and removing
|
||||||
await nuxtApp.callHook('app:redirected')
|
await nuxtApp.callHook('app:redirected')
|
||||||
const encodedLoc = location.replace(/"/g, '%22')
|
const encodedLoc = location.replace(/"/g, '%22')
|
||||||
@ -127,16 +127,16 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
|
|||||||
body: `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`,
|
body: `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`,
|
||||||
headers: { location }
|
headers: { location }
|
||||||
}
|
}
|
||||||
return inMiddleware ? /* abort route navigation */ false : undefined
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
// We wait to perform the redirect last in case any other middleware will intercept the redirect
|
// We wait to perform the redirect last in case any other middleware will intercept the redirect
|
||||||
// and redirect somewhere else instead.
|
// and redirect somewhere else instead.
|
||||||
if (!isExternal && inMiddleware) {
|
if (!isExternal && inMiddleware) {
|
||||||
router.afterEach(final => (final.fullPath === fullPath) ? redirect() : undefined)
|
router.afterEach(final => final.fullPath === fullPath ? redirect(false) : undefined)
|
||||||
return to
|
return to
|
||||||
}
|
}
|
||||||
return redirect()
|
return redirect(!inMiddleware ? undefined : /* abort route navigation */ false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ if (process.server) {
|
|||||||
await nuxt.hooks.callHook('app:error', err)
|
await nuxt.hooks.callHook('app:error', err)
|
||||||
nuxt.payload.error = (nuxt.payload.error || err) as any
|
nuxt.payload.error = (nuxt.payload.error || err) as any
|
||||||
}
|
}
|
||||||
|
if (ssrContext?._renderResponse) { throw new Error('skipping render') }
|
||||||
|
|
||||||
return vueApp
|
return vueApp
|
||||||
}
|
}
|
||||||
|
@ -247,6 +247,9 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
|||||||
}
|
}
|
||||||
|
|
||||||
const _rendered = await renderer.renderToString(ssrContext).catch(async (error) => {
|
const _rendered = await renderer.renderToString(ssrContext).catch(async (error) => {
|
||||||
|
// We use error to bypass full render if we have an early response we can make
|
||||||
|
if (ssrContext._renderResponse && error.message === 'skipping render') { return {} as ReturnType<typeof renderer['renderToString']> }
|
||||||
|
|
||||||
// Use explicitly thrown error in preference to subsequent rendering errors
|
// Use explicitly thrown error in preference to subsequent rendering errors
|
||||||
const _err = (!ssrError && ssrContext.payload?.error) || error
|
const _err = (!ssrError && ssrContext.payload?.error) || error
|
||||||
await ssrContext.nuxt?.hooks.callHook('app:error', _err)
|
await ssrContext.nuxt?.hooks.callHook('app:error', _err)
|
||||||
|
@ -633,6 +633,13 @@ describe('navigate', () => {
|
|||||||
expect(status).toEqual(302)
|
expect(status).toEqual(302)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should not run setup function in path redirected to', async () => {
|
||||||
|
const { headers, status } = await fetch('/navigate-to-error', { redirect: 'manual' })
|
||||||
|
|
||||||
|
expect(headers.get('location')).toEqual('/setup-should-not-run')
|
||||||
|
expect(status).toEqual(302)
|
||||||
|
})
|
||||||
|
|
||||||
it('supports directly aborting navigation on SSR', async () => {
|
it('supports directly aborting navigation on SSR', async () => {
|
||||||
const { status } = await fetch('/navigate-to-false', { redirect: 'manual' })
|
const { status } = await fetch('/navigate-to-false', { redirect: 'manual' })
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ describe.skipIf(isWindows || process.env.TEST_BUILDER === 'webpack' || process.e
|
|||||||
|
|
||||||
it('default server bundle size', async () => {
|
it('default server bundle size', async () => {
|
||||||
stats.server = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
stats.server = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||||
expect(roundToKilobytes(stats.server.totalBytes)).toMatchInlineSnapshot('"62.6k"')
|
expect(roundToKilobytes(stats.server.totalBytes)).toMatchInlineSnapshot('"62.8k"')
|
||||||
|
|
||||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||||
expect(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2285k"')
|
expect(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2285k"')
|
||||||
|
14
test/fixtures/basic/pages/navigate-to-error.vue
vendored
Normal file
14
test/fixtures/basic/pages/navigate-to-error.vue
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<div>You should not see me</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
definePageMeta({
|
||||||
|
alias: ['/setup-should-not-run'],
|
||||||
|
middleware: to => to.path === '/navigate-to-error' ? navigateTo('/setup-should-not-run') : undefined
|
||||||
|
})
|
||||||
|
console.log('running setup')
|
||||||
|
useNuxtApp().hook('app:rendered', () => {
|
||||||
|
throw new Error('this should not run')
|
||||||
|
})
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user