diff --git a/src/core/config/resolvers/route-rules.ts b/src/core/config/resolvers/route-rules.ts index 2071b42ca3..15a899c53d 100644 --- a/src/core/config/resolvers/route-rules.ts +++ b/src/core/config/resolvers/route-rules.ts @@ -5,6 +5,7 @@ import type { NitroRouteConfig, NitroRouteRules, } from "nitropack/types"; +import { withLeadingSlash } from "ufo"; export async function resolveRouteRulesOptions(options: NitroOptions) { // Backward compatibility for options.routes @@ -17,8 +18,9 @@ export function normalizeRouteRules( config: NitroConfig ): Record { const normalizedRules: Record = {}; - for (const path in config.routeRules) { + for (let path in config.routeRules) { const routeConfig = config.routeRules[path] as NitroRouteConfig; + path = withLeadingSlash(path); const routeRules: NitroRouteRules = { ...routeConfig, redirect: undefined, diff --git a/test/fixture/nitro.config.ts b/test/fixture/nitro.config.ts index c9f35e67d2..61cc76149f 100644 --- a/test/fixture/nitro.config.ts +++ b/test/fixture/nitro.config.ts @@ -95,6 +95,7 @@ export default defineNitroConfig({ "/rules/_/cached/noncached": { cache: false, swr: false, isr: false }, "/rules/_/cached/**": { swr: true }, "/api/proxy/**": { proxy: "/api/echo" }, + "**": { headers: { "x-test": "test" } }, }, prerender: { crawlLinks: true, diff --git a/test/presets/netlify-legacy.test.ts b/test/presets/netlify-legacy.test.ts index 5de5771d7f..a122c62188 100644 --- a/test/presets/netlify-legacy.test.ts +++ b/test/presets/netlify-legacy.test.ts @@ -82,19 +82,21 @@ describe("nitro:preset:netlify-legacy", async () => { ); expect(headers).toMatchInlineSnapshot(` - "/rules/headers - cache-control: s-maxage=60 - /rules/cors - access-control-allow-origin: * - access-control-allow-methods: GET - access-control-allow-headers: * - access-control-max-age: 0 - /rules/nested/* - x-test: test - /build/* - cache-control: public, max-age=3600, immutable - " - `); + "/rules/headers + cache-control: s-maxage=60 + /rules/cors + access-control-allow-origin: * + access-control-allow-methods: GET + access-control-allow-headers: * + access-control-max-age: 0 + /rules/nested/* + x-test: test + /build/* + cache-control: public, max-age=3600, immutable + /* + x-test: test + " + `); }); it("should write config.json", async () => { const config = await fsp diff --git a/test/presets/netlify.test.ts b/test/presets/netlify.test.ts index 6cb2b58ea1..9740795250 100644 --- a/test/presets/netlify.test.ts +++ b/test/presets/netlify.test.ts @@ -62,19 +62,21 @@ describe("nitro:preset:netlify", async () => { ); expect(headers).toMatchInlineSnapshot(` - "/rules/headers - cache-control: s-maxage=60 - /rules/cors - access-control-allow-origin: * - access-control-allow-methods: GET - access-control-allow-headers: * - access-control-max-age: 0 - /rules/nested/* - x-test: test - /build/* - cache-control: public, max-age=3600, immutable - " - `); + "/rules/headers + cache-control: s-maxage=60 + /rules/cors + access-control-allow-origin: * + access-control-allow-methods: GET + access-control-allow-headers: * + access-control-max-age: 0 + /rules/nested/* + x-test: test + /build/* + cache-control: public, max-age=3600, immutable + /* + x-test: test + " + `); }); it("writes config.json", async () => { diff --git a/test/presets/vercel.test.ts b/test/presets/vercel.test.ts index 25ad76cfe2..3b10b698b3 100644 --- a/test/presets/vercel.test.ts +++ b/test/presets/vercel.test.ts @@ -96,6 +96,12 @@ describe("nitro:preset:vercel", async () => { }, "src": "/build/(.*)", }, + { + "headers": { + "x-test": "test", + }, + "src": "/(.*)", + }, { "continue": true, "headers": {