From 6b7abce0ffcdf92f76a9128f270a15814ad1a45f Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 22 Sep 2022 09:22:21 +0100 Subject: [PATCH 1/2] feat(nuxt): support `redirect` within page metadata --- packages/nuxt/src/pages/runtime/composables.ts | 14 +++++++++++++- packages/nuxt/src/pages/utils.ts | 1 + test/basic.test.ts | 10 ++++++++++ test/fixtures/basic/pages/index.vue | 4 ++++ test/fixtures/basic/pages/redirect.vue | 11 +++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/basic/pages/redirect.vue diff --git a/packages/nuxt/src/pages/runtime/composables.ts b/packages/nuxt/src/pages/runtime/composables.ts index 737c24f509b..2b6e0e67303 100644 --- a/packages/nuxt/src/pages/runtime/composables.ts +++ b/packages/nuxt/src/pages/runtime/composables.ts @@ -1,8 +1,20 @@ import { KeepAliveProps, TransitionProps, UnwrapRef } from 'vue' -import type { RouteLocationNormalizedLoaded } from 'vue-router' +import type { RouteLocationNormalizedLoaded, RouteRecordRedirectOption } from 'vue-router' export interface PageMeta { [key: string]: any + /** + * Where to redirect if the route is directly matched. The redirection happens + * before any navigation guard and triggers a new navigation with the new + * target location. + */ + redirect?: RouteRecordRedirectOption + /** + * Aliases for the record. Allows defining extra paths that will behave like a + * copy of the record. Allows having paths shorthands like `/users/:id` and + * `/u/:id`. All `alias` and `path` values must share the same params. + */ + alias?: string | string[] pageTransition?: boolean | TransitionProps layoutTransition?: boolean | TransitionProps key?: false | string | ((route: RouteLocationNormalizedLoaded) => string) diff --git a/packages/nuxt/src/pages/utils.ts b/packages/nuxt/src/pages/utils.ts index 1556daf787b..4e0c878abe0 100644 --- a/packages/nuxt/src/pages/utils.ts +++ b/packages/nuxt/src/pages/utils.ts @@ -243,6 +243,7 @@ export function normalizeRoutes (routes: NuxtPage[], metaImports: Set = children: route.children ? normalizeRoutes(route.children, metaImports).routes : [], meta: route.meta ? `{...(${metaImportName} || {}), ...${JSON.stringify(route.meta)}}` : metaImportName, alias: aliasCode, + redirect: `${metaImportName}?.redirect || undefined`, component: genDynamicImport(file, { interopDefault: true }) } })) diff --git a/test/basic.test.ts b/test/basic.test.ts index 9116bc51db8..2fe9c019dba 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -55,6 +55,16 @@ describe('pages', () => { await expectNoClientErrors('/') }) + it('respects aliases in page metadata', async () => { + const html = await $fetch('/some-alias') + expect(html).toContain('Hello Nuxt 3!') + }) + + it('respects redirects in page metadata', async () => { + const { headers } = await fetch('/redirect', { redirect: 'manual' }) + expect(headers.get('location')).toEqual('/') + }) + it('render 404', async () => { const html = await $fetch('/not-found') diff --git a/test/fixtures/basic/pages/index.vue b/test/fixtures/basic/pages/index.vue index 69856bb302b..eb335bfca56 100644 --- a/test/fixtures/basic/pages/index.vue +++ b/test/fixtures/basic/pages/index.vue @@ -28,6 +28,10 @@ setupDevtoolsPlugin({}, () => {}) const config = useRuntimeConfig() +definePageMeta({ + alias: '/some-alias' +}) + // reset title template example useHead({ titleTemplate: '' diff --git a/test/fixtures/basic/pages/redirect.vue b/test/fixtures/basic/pages/redirect.vue new file mode 100644 index 00000000000..3ef5f992d4e --- /dev/null +++ b/test/fixtures/basic/pages/redirect.vue @@ -0,0 +1,11 @@ + + + From 8706b67cf5254f0dc045a6f3f666348460062811 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 22 Sep 2022 09:25:14 +0100 Subject: [PATCH 2/2] fix: respect redirect within routes array --- packages/nuxt/src/pages/utils.ts | 2 +- packages/schema/src/types/hooks.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/nuxt/src/pages/utils.ts b/packages/nuxt/src/pages/utils.ts index 4e0c878abe0..2bc25b3f0a5 100644 --- a/packages/nuxt/src/pages/utils.ts +++ b/packages/nuxt/src/pages/utils.ts @@ -243,7 +243,7 @@ export function normalizeRoutes (routes: NuxtPage[], metaImports: Set = children: route.children ? normalizeRoutes(route.children, metaImports).routes : [], meta: route.meta ? `{...(${metaImportName} || {}), ...${JSON.stringify(route.meta)}}` : metaImportName, alias: aliasCode, - redirect: `${metaImportName}?.redirect || undefined`, + redirect: route.redirect ? JSON.stringify(route.redirect) : `${metaImportName}?.redirect || undefined`, component: genDynamicImport(file, { interopDefault: true }) } })) diff --git a/packages/schema/src/types/hooks.ts b/packages/schema/src/types/hooks.ts index 1e3d5d036c2..b0df1adeb82 100644 --- a/packages/schema/src/types/hooks.ts +++ b/packages/schema/src/types/hooks.ts @@ -43,7 +43,8 @@ export type NuxtPage = { path: string file: string meta?: Record - alias?: string[] + alias?: string[] | string + redirect?: string children?: NuxtPage[] }