From c30070b9271e4c494e7cbf3a1c45515782034911 Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Mon, 13 Jan 2025 11:05:44 -0500 Subject: [PATCH] fix: 404 and 500 route matching (#12182) Co-authored-by: Florian Lefebvre --- .changeset/purple-swans-argue.md | 5 +++++ packages/astro/src/core/routing/match.ts | 13 ++++++++++++- packages/astro/src/i18n/index.ts | 4 +++- .../astro/src/vite-plugin-astro-server/route.ts | 7 +++---- 4 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 .changeset/purple-swans-argue.md diff --git a/.changeset/purple-swans-argue.md b/.changeset/purple-swans-argue.md new file mode 100644 index 000000000000..d96a2fbd8e10 --- /dev/null +++ b/.changeset/purple-swans-argue.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Improves matching of 404 and 500 routes diff --git a/packages/astro/src/core/routing/match.ts b/packages/astro/src/core/routing/match.ts index 0e8a9e3387e4..d8ead2f0703b 100644 --- a/packages/astro/src/core/routing/match.ts +++ b/packages/astro/src/core/routing/match.ts @@ -17,6 +17,17 @@ export function matchAllRoutes(pathname: string, manifest: ManifestData): RouteD return manifest.routes.filter((route) => route.pattern.test(decodeURI(pathname))); } +const ROUTE404_RE = /^\/404\/?$/; +const ROUTE500_RE = /^\/500\/?$/; + +export function isRoute404(route: string) { + return ROUTE404_RE.test(route); +} + +export function isRoute500(route: string) { + return ROUTE500_RE.test(route); +} + /** * Determines if the given route matches a 404 or 500 error page. * @@ -24,5 +35,5 @@ export function matchAllRoutes(pathname: string, manifest: ManifestData): RouteD * @returns {boolean} `true` if the route matches a 404 or 500 error page, otherwise `false`. */ export function isRoute404or500(route: RouteData): boolean { - return route.pattern.test('/404') || route.pattern.test('/500'); + return isRoute404(route.route) || isRoute500(route.route); } diff --git a/packages/astro/src/i18n/index.ts b/packages/astro/src/i18n/index.ts index e1e3750ea40b..59da491a1d1f 100644 --- a/packages/astro/src/i18n/index.ts +++ b/packages/astro/src/i18n/index.ts @@ -4,6 +4,7 @@ import { shouldAppendForwardSlash } from '../core/build/util.js'; import { REROUTE_DIRECTIVE_HEADER } from '../core/constants.js'; import { MissingLocale, i18nNoLocaleFoundInPath } from '../core/errors/errors-data.js'; import { AstroError } from '../core/errors/index.js'; +import { isRoute404, isRoute500 } from '../core/routing/match.js'; import type { AstroConfig, Locales, ValidRedirectStatus } from '../types/public/config.js'; import type { APIContext } from '../types/public/context.js'; import { createI18nMiddleware } from './middleware.js'; @@ -17,8 +18,9 @@ export function requestHasLocale(locales: Locales) { export function requestIs404Or500(request: Request, base = '') { const url = new URL(request.url); + const pathname = url.pathname.slice(base.length); - return url.pathname.startsWith(`${base}/404`) || url.pathname.startsWith(`${base}/500`); + return isRoute404(pathname) || isRoute500(pathname); } // Checks if the pathname has any locale diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts index 025ba1e75cbe..51b7537bfc4a 100644 --- a/packages/astro/src/vite-plugin-astro-server/route.ts +++ b/packages/astro/src/vite-plugin-astro-server/route.ts @@ -15,6 +15,7 @@ import { getProps } from '../core/render/index.js'; import { createRequest } from '../core/request.js'; import { redirectTemplate } from '../core/routing/3xx.js'; import { matchAllRoutes } from '../core/routing/index.js'; +import { isRoute404, isRoute500 } from '../core/routing/match.js'; import { PERSIST_SYMBOL } from '../core/session.js'; import { getSortedPreloadedMatches } from '../prerender/routing.js'; import type { ComponentInstance, ManifestData } from '../types/astro.js'; @@ -41,13 +42,11 @@ function isLoggedRequest(url: string) { } function getCustom404Route(manifestData: ManifestData): RouteData | undefined { - const route404 = /^\/404\/?$/; - return manifestData.routes.find((r) => route404.test(r.route)); + return manifestData.routes.find((r) => isRoute404(r.route)); } function getCustom500Route(manifestData: ManifestData): RouteData | undefined { - const route500 = /^\/500\/?$/; - return manifestData.routes.find((r) => route500.test(r.route)); + return manifestData.routes.find((r) => isRoute500(r.route)); } export async function matchRoute(