diff --git a/packages/nuxt/src/app/composables/manifest.ts b/packages/nuxt/src/app/composables/manifest.ts index 5a293e6f9a..d2ec8a58df 100644 --- a/packages/nuxt/src/app/composables/manifest.ts +++ b/packages/nuxt/src/app/composables/manifest.ts @@ -1,6 +1,8 @@ import type { MatcherExport, RouteMatcher } from 'radix3' import { createMatcherFromExport, createRouter as createRadixRouter, toRouteMatcher } from 'radix3' import { defu } from 'defu' +import type { H3Event } from 'h3' +import type { NitroRouteRules } from 'nitro/types' import { useNuxtApp, useRuntimeConfig } from '../nuxt' // @ts-expect-error virtual file import { appManifest as isAppManifestEnabled } from '#build/nuxt.config.mjs' @@ -52,13 +54,18 @@ export function getAppManifest (): Promise { } /** @since 3.7.4 */ -export async function getRouteRules (url: string) { +export async function getRouteRules (event: H3Event): Promise +export async function getRouteRules (options: { path: string }): Promise> +/** @deprecated use `getRouteRules({ path })` instead */ +export async function getRouteRules (url: string): Promise> +export async function getRouteRules (arg: string | H3Event | { path: string }) { + const path = typeof arg === 'string' ? arg : arg.path if (import.meta.server) { useNuxtApp().ssrContext!._preloadManifest = true const _routeRulesMatcher = toRouteMatcher( createRadixRouter({ routes: useRuntimeConfig().nitro!.routeRules }), ) - return defu({} as Record, ..._routeRulesMatcher.matchAll(url).reverse()) + return defu({} as Record, ..._routeRulesMatcher.matchAll(path).reverse()) } await getAppManifest() if (!matcher) { @@ -66,7 +73,7 @@ export async function getRouteRules (url: string) { return {} } try { - return defu({} as Record, ...matcher.matchAll(url).reverse()) + return defu({} as Record, ...matcher.matchAll(path).reverse()) } catch (e) { console.error('[nuxt] Error matching route rules.', e) return {} diff --git a/packages/nuxt/src/app/composables/payload.ts b/packages/nuxt/src/app/composables/payload.ts index f2107afd8e..aba25a2053 100644 --- a/packages/nuxt/src/app/composables/payload.ts +++ b/packages/nuxt/src/app/composables/payload.ts @@ -94,7 +94,7 @@ export async function isPrerendered (url = useRoute().path) { return true } return nuxtApp.runWithContext(async () => { - const rules = await getRouteRules(url) + const rules = await getRouteRules({ path: url }) return !!rules.prerender && !rules.redirect }) } diff --git a/packages/nuxt/src/app/middleware/manifest-route-rule.ts b/packages/nuxt/src/app/middleware/manifest-route-rule.ts index ef3d2e1d37..0aeb4defce 100644 --- a/packages/nuxt/src/app/middleware/manifest-route-rule.ts +++ b/packages/nuxt/src/app/middleware/manifest-route-rule.ts @@ -4,7 +4,7 @@ import { getRouteRules } from '../composables/manifest' export default defineNuxtRouteMiddleware(async (to) => { if (import.meta.server || import.meta.test) { return } - const rules = await getRouteRules(to.path) + const rules = await getRouteRules({ path: to.path }) if (rules.redirect) { if (hasProtocol(rules.redirect, { acceptRelative: true })) { window.location.href = rules.redirect diff --git a/packages/nuxt/src/app/plugins/router.ts b/packages/nuxt/src/app/plugins/router.ts index 207232e6bc..dbac6d4634 100644 --- a/packages/nuxt/src/app/plugins/router.ts +++ b/packages/nuxt/src/app/plugins/router.ts @@ -248,7 +248,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({ const middlewareEntries = new Set([...globalMiddleware, ...nuxtApp._middleware.global]) if (isAppManifestEnabled) { - const routeRules = await nuxtApp.runWithContext(() => getRouteRules(to.path)) + const routeRules = await nuxtApp.runWithContext(() => getRouteRules({ path: to.path })) if (routeRules.appMiddleware) { for (const key in routeRules.appMiddleware) { diff --git a/packages/nuxt/src/pages/runtime/plugins/router.ts b/packages/nuxt/src/pages/runtime/plugins/router.ts index 894d915a5d..9fc439cf0d 100644 --- a/packages/nuxt/src/pages/runtime/plugins/router.ts +++ b/packages/nuxt/src/pages/runtime/plugins/router.ts @@ -199,7 +199,7 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({ } if (isAppManifestEnabled) { - const routeRules = await nuxtApp.runWithContext(() => getRouteRules(to.path)) + const routeRules = await nuxtApp.runWithContext(() => getRouteRules({ path: to.path })) if (routeRules.appMiddleware) { for (const key in routeRules.appMiddleware) { diff --git a/test/fixtures/basic-types/types.ts b/test/fixtures/basic-types/types.ts index 7e022eaa0e..204e980d97 100644 --- a/test/fixtures/basic-types/types.ts +++ b/test/fixtures/basic-types/types.ts @@ -2,6 +2,9 @@ import { describe, expectTypeOf, it } from 'vitest' import type { Ref, SlotsType } from 'vue' import type { FetchError } from 'ofetch' import type { NavigationFailure, RouteLocationNormalized, RouteLocationRaw, Router, useRouter as vueUseRouter } from 'vue-router' +import type { H3Event } from 'h3' +import { getRouteRules as getNitroRouteRules } from 'nitro/runtime' +import type { NitroRouteRules } from 'nitro/types' import type { AppConfig, RuntimeValue, UpperSnakeCase } from 'nuxt/schema' import { defineNuxtModule } from 'nuxt/kit' @@ -110,6 +113,21 @@ describe('API routes', () => { }) }) +describe('nitro compatible APIs', () => { + it('getRouteRules', async () => { + const a = await getRouteRules('/test') + const b = await getRouteRules({} as H3Event) + const c = getNitroRouteRules({} as H3Event) + + expectTypeOf(b).toEqualTypeOf(c) + expectTypeOf(c).toEqualTypeOf() + expectTypeOf(a).toEqualTypeOf>() + }) + it('useRuntimeConfig', () => { + useRuntimeConfig({} as H3Event) + }) +}) + describe('aliases', () => { it('allows importing from path aliases', () => { expectTypeOf(useRouter).toEqualTypeOf() diff --git a/test/nuxt/composables.test.ts b/test/nuxt/composables.test.ts index 43fe151a92..bfb0eed5d1 100644 --- a/test/nuxt/composables.test.ts +++ b/test/nuxt/composables.test.ts @@ -557,8 +557,8 @@ describe.skipIf(process.env.TEST_MANIFEST === 'manifest-off')('app manifests', ( `) }) it('getRouteRules', async () => { - expect(await getRouteRules('/')).toMatchInlineSnapshot('{}') - expect(await getRouteRules('/pre')).toMatchInlineSnapshot(` + expect(await getRouteRules({ path: '/' })).toMatchInlineSnapshot('{}') + expect(await getRouteRules({ path: '/pre' })).toMatchInlineSnapshot(` { "prerender": true, }