summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/hot-dingos-dress.md5
-rw-r--r--packages/astro/src/i18n/middleware.ts8
-rw-r--r--packages/astro/src/vite-plugin-astro-server/request.ts1
-rw-r--r--packages/astro/src/vite-plugin-astro-server/route.ts32
-rw-r--r--packages/astro/test/fixtures/i18n-routing/src/pages/404.astro1
-rw-r--r--packages/astro/test/i18n-routing.test.js6
6 files changed, 28 insertions, 25 deletions
diff --git a/.changeset/hot-dingos-dress.md b/.changeset/hot-dingos-dress.md
new file mode 100644
index 000000000..8a7087643
--- /dev/null
+++ b/.changeset/hot-dingos-dress.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixes an issue where with `i18n` enabled, Astro couldn't render the `404.astro` component for non-existent routes.
diff --git a/packages/astro/src/i18n/middleware.ts b/packages/astro/src/i18n/middleware.ts
index 097332805..f4649dce2 100644
--- a/packages/astro/src/i18n/middleware.ts
+++ b/packages/astro/src/i18n/middleware.ts
@@ -1,6 +1,6 @@
import type { APIContext, MiddlewareHandler, SSRManifest } from '../@types/astro.js';
import type { SSRManifestI18n } from '../core/app/types.js';
-import { ROUTE_TYPE_HEADER } from '../core/constants.js';
+import { REROUTE_DIRECTIVE_HEADER, ROUTE_TYPE_HEADER } from '../core/constants.js';
import {
type MiddlewarePayload,
normalizeTheLocale,
@@ -65,6 +65,12 @@ export function createI18nMiddleware(
return async (context, next) => {
const response = await next();
const type = response.headers.get(ROUTE_TYPE_HEADER);
+
+ // This is case where we are internally rendering a 404/500, so we need to bypass checks that were done already
+ const isReroute = response.headers.get(REROUTE_DIRECTIVE_HEADER);
+ if (isReroute === 'no' && typeof i18n.fallback === 'undefined') {
+ return response;
+ }
// If the route we're processing is not a page, then we ignore it
if (type !== 'page' && type !== 'fallback') {
return response;
diff --git a/packages/astro/src/vite-plugin-astro-server/request.ts b/packages/astro/src/vite-plugin-astro-server/request.ts
index b231bfde3..d45cf8b55 100644
--- a/packages/astro/src/vite-plugin-astro-server/request.ts
+++ b/packages/astro/src/vite-plugin-astro-server/request.ts
@@ -63,7 +63,6 @@ export async function handleRequest({
url,
pathname: resolvedPathname,
body,
- origin,
pipeline,
manifestData,
incomingRequest: incomingRequest,
diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts
index 8de52d158..5e888ceaf 100644
--- a/packages/astro/src/vite-plugin-astro-server/route.ts
+++ b/packages/astro/src/vite-plugin-astro-server/route.ts
@@ -127,7 +127,6 @@ type HandleRoute = {
url: URL;
pathname: string;
body: ArrayBuffer | undefined;
- origin: string;
manifestData: ManifestData;
incomingRequest: http.IncomingMessage;
incomingResponse: http.ServerResponse;
@@ -139,7 +138,6 @@ export async function handleRoute({
url,
pathname,
body,
- origin,
pipeline,
manifestData,
incomingRequest,
@@ -156,12 +154,10 @@ export async function handleRoute({
let request: Request;
let renderContext: RenderContext;
let mod: ComponentInstance | undefined = undefined;
- let options: SSROptions | undefined = undefined;
let route: RouteData;
const middleware = (await loadMiddleware(loader)).onRequest;
const locals = Reflect.get(incomingRequest, clientLocalsSymbol);
- const filePath: URL | undefined = matchedRoute.filePath;
const { preloadedComponent } = matchedRoute;
route = matchedRoute.route;
// Allows adapters to pass in locals in dev mode.
@@ -181,15 +177,6 @@ export async function handleRoute({
if (value) incomingResponse.setHeader(name, value);
}
- options = {
- pipeline,
- filePath,
- preload: preloadedComponent,
- pathname,
- request,
- route,
- };
-
mod = preloadedComponent;
renderContext = await RenderContext.create({
@@ -248,18 +235,17 @@ export async function handleRoute({
if (statusCode === 404 && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== 'no') {
const fourOhFourRoute = await matchRoute('/404', manifestData, pipeline);
- if (options && options.route !== fourOhFourRoute?.route)
- return handleRoute({
- ...options,
- matchedRoute: fourOhFourRoute,
- url: new URL(pathname, url),
- body,
- origin,
+ if (fourOhFourRoute) {
+ renderContext = await RenderContext.create({
+ locals,
pipeline,
- manifestData,
- incomingRequest,
- incomingResponse,
+ pathname,
+ middleware: isDefaultPrerendered404(fourOhFourRoute.route) ? undefined : middleware,
+ request,
+ routeData: fourOhFourRoute.route,
});
+ response = await renderContext.render(fourOhFourRoute.preloadedComponent);
+ }
}
// We remove the internally-used header before we send the response to the user agent.
diff --git a/packages/astro/test/fixtures/i18n-routing/src/pages/404.astro b/packages/astro/test/fixtures/i18n-routing/src/pages/404.astro
index fce4a30b8..bfde75373 100644
--- a/packages/astro/test/fixtures/i18n-routing/src/pages/404.astro
+++ b/packages/astro/test/fixtures/i18n-routing/src/pages/404.astro
@@ -7,6 +7,7 @@ const currentLocale = Astro.currentLocale;
</head>
<body>
<h1>404 - Not Found</h1>
+ <h2>Custom 404</h2>
<p>Current Locale: {currentLocale ? currentLocale : "none"}</p>
</body>
</html>
diff --git a/packages/astro/test/i18n-routing.test.js b/packages/astro/test/i18n-routing.test.js
index 8e6c672be..b55703827 100644
--- a/packages/astro/test/i18n-routing.test.js
+++ b/packages/astro/test/i18n-routing.test.js
@@ -83,6 +83,12 @@ describe('[DEV] i18n routing', () => {
assert.equal((await response.text()).includes('Endurance'), true);
});
+ it('should render the 404.astro file', async () => {
+ const response = await fixture.fetch('/do-not-exist');
+ assert.equal(response.status, 404);
+ assert.match(await response.text(), /Custom 404/);
+ });
+
it('should return the correct locale on 404 page for non existing default locale page', async () => {
const response = await fixture.fetch('/es/nonexistent-page');
assert.equal(response.status, 404);