Skip to content

Commit

Permalink
fix(i18n): render 404.astro when i18n is enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico committed Nov 25, 2024
1 parent c6a31e3 commit 8deb774
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 28 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-dingos-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes an issue where `i18n` is enabled, Astro couldn't render the `404.astro` component when navigating non-existent routes.
8 changes: 7 additions & 1 deletion packages/astro/src/i18n/middleware.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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;
Expand Down
31 changes: 9 additions & 22 deletions packages/astro/src/vite-plugin-astro-server/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ type HandleRoute = {
url: URL;
pathname: string;
body: ArrayBuffer | undefined;
origin: string;
manifestData: ManifestData;
incomingRequest: http.IncomingMessage;
incomingResponse: http.ServerResponse;
Expand All @@ -139,7 +138,6 @@ export async function handleRoute({
url,
pathname,
body,
origin,
pipeline,
manifestData,
incomingRequest,
Expand All @@ -156,7 +154,6 @@ 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);
Expand All @@ -181,15 +178,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({
Expand Down Expand Up @@ -248,18 +236,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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
6 changes: 6 additions & 0 deletions packages/astro/test/i18n-routing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 0 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8deb774

Please sign in to comment.