From 370b84e909ab0ec311f44e9daa915a6fda1885ed Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 6 Jun 2023 22:47:32 +0100 Subject: [PATCH] fix(nuxt): handle page rendering on different path (#21408) --- packages/nuxt/src/app/nuxt.ts | 9 +++++---- packages/nuxt/src/core/runtime/nitro/renderer.ts | 1 + packages/nuxt/src/pages/runtime/plugins/router.ts | 12 ++++++++---- test/basic.test.ts | 9 +++++++++ test/bundle.test.ts | 2 +- test/fixtures/basic/server/routes/proxy.ts | 3 +++ 6 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/basic/server/routes/proxy.ts diff --git a/packages/nuxt/src/app/nuxt.ts b/packages/nuxt/src/app/nuxt.ts index 0346f93918..68c6453b0b 100644 --- a/packages/nuxt/src/app/nuxt.ts +++ b/packages/nuxt/src/app/nuxt.ts @@ -119,6 +119,7 @@ interface _NuxtApp { ssrContext?: NuxtSSRContext payload: { + path?: string serverRendered?: boolean prerenderedAt?: number data: Record @@ -255,13 +256,13 @@ export function createNuxtApp (options: CreateOptions) { defineGetter(nuxtApp.vueApp.config.globalProperties, '$nuxt', nuxtApp) if (process.server) { - // Expose nuxt to the renderContext if (nuxtApp.ssrContext) { + // Expose nuxt to the renderContext nuxtApp.ssrContext.nuxt = nuxtApp - } - // Expose payload types - if (nuxtApp.ssrContext) { + // Expose payload types nuxtApp.ssrContext._payloadReducers = {} + // Expose current path + nuxtApp.payload.path = nuxtApp.ssrContext.event.path } // Expose to server renderer to create payload nuxtApp.ssrContext = nuxtApp.ssrContext || {} as any diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index ab47538628..3d05ef728e 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -122,6 +122,7 @@ const getSPARenderer = lazyCachedFunction(async () => { const renderToString = (ssrContext: NuxtSSRContext) => { const config = useRuntimeConfig() ssrContext!.payload = { + path: ssrContext.event.path, _errors: {}, serverRendered: false, data: {}, diff --git a/packages/nuxt/src/pages/runtime/plugins/router.ts b/packages/nuxt/src/pages/runtime/plugins/router.ts index 28fcca3c73..8427831bd4 100644 --- a/packages/nuxt/src/pages/runtime/plugins/router.ts +++ b/packages/nuxt/src/pages/runtime/plugins/router.ts @@ -27,7 +27,8 @@ import { globalMiddleware, namedMiddleware } from '#build/middleware' // https://github.com/vuejs/router/blob/4a0cc8b9c1e642cdf47cc007fa5bbebde70afc66/packages/router/src/history/html5.ts#L37 function createCurrentLocation ( base: string, - location: Location + location: Location, + renderedPath?: string ): string { const { pathname, search, hash } = location // allows hash bases like #, /#, #/, #!, #!/, /#!/, or even /folder#end @@ -41,8 +42,8 @@ function createCurrentLocation ( if (pathFromHash[0] !== '/') { pathFromHash = '/' + pathFromHash } return withoutBase(pathFromHash, '') } - const path = withoutBase(pathname, base) - return path + search + hash + const path = renderedPath || withoutBase(pathname, base) + return path + (path.includes('?') ? '' : search) + hash } const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({ @@ -63,7 +64,10 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({ const routes = routerOptions.routes?.(_routes) ?? _routes let startPosition: Parameters[2] | null - const initialURL = process.server ? nuxtApp.ssrContext!.url : createCurrentLocation(routerBase, window.location) + const initialURL = process.server + ? nuxtApp.ssrContext!.url + : createCurrentLocation(routerBase, window.location, nuxtApp.payload.path) + const router = createRouter({ ...routerOptions, scrollBehavior: (to, from, savedPosition) => { diff --git a/test/basic.test.ts b/test/basic.test.ts index 272befcd7c..113ef10c20 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -162,6 +162,15 @@ describe('pages', () => { await expectNoClientErrors('/not-found') }) + it('should render correctly when loaded on a different path', async () => { + const page = await createPage('/proxy') + + await page.waitForLoadState('networkidle') + expect(await page.innerText('body')).toContain('Composable | foo: auto imported from ~/composables/foo.ts') + + await expectNoClientErrors('/proxy') + }) + it('preserves query', async () => { const html = await $fetch('/?test=true') diff --git a/test/bundle.test.ts b/test/bundle.test.ts index 8edc3a0551..d27fa91e74 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -45,7 +45,7 @@ describe.skipIf(isWindows || process.env.TEST_BUILDER === 'webpack' || process.e it('default server bundle size', async () => { stats.server = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir) - expect(roundToKilobytes(stats.server.totalBytes)).toMatchInlineSnapshot('"62.4k"') + expect(roundToKilobytes(stats.server.totalBytes)).toMatchInlineSnapshot('"62.5k"') const modules = await analyzeSizes('node_modules/**/*', serverDir) expect(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2284k"') diff --git a/test/fixtures/basic/server/routes/proxy.ts b/test/fixtures/basic/server/routes/proxy.ts new file mode 100644 index 0000000000..63ddb05778 --- /dev/null +++ b/test/fixtures/basic/server/routes/proxy.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(async () => { + return await $fetch('/') +})