Skip to content

Commit 16f12e4

Browse files
ematipicoflorian-lefebvre
andauthoredMay 16, 2024··
fix(i18n): allow to create 404.html and 500.html (#11062)
* fix(i18n): allow to create 404.html and 500.html * Update packages/astro/src/i18n/index.ts Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev> * Update .changeset/lazy-rockets-raise.md * chore: use better matching * fix linting --------- Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>
1 parent 3a0c02a commit 16f12e4

File tree

6 files changed

+37
-3
lines changed

6 files changed

+37
-3
lines changed
 

‎.changeset/lazy-rockets-raise.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"astro": patch
3+
---
4+
5+
Fixes a bug where `astro build` didn't create custom `404.html` and `500.html` when a certain combination of i18n options was applied

‎packages/astro/src/i18n/index.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ export function requestHasLocale(locales: Locales) {
1919
};
2020
}
2121

22+
export function requestIs404Or500(request: Request, base = '') {
23+
const url = new URL(request.url);
24+
25+
return (
26+
url.pathname.startsWith(`${base}/404`) ||
27+
url.pathname.startsWith(`${base}/500`)
28+
);
29+
}
2230
// Checks if the pathname has any locale
2331
export function pathHasLocale(path: string, locales: Locales): boolean {
2432
const segments = path.split('/');
@@ -317,7 +325,7 @@ export function notFound({ base, locales }: MiddlewarePayload) {
317325
if (!(isRoot || pathHasLocale(url.pathname, locales))) {
318326
if (response) {
319327
response.headers.set(REROUTE_DIRECTIVE_HEADER, 'no');
320-
return new Response(null, {
328+
return new Response(response.body, {
321329
status: 404,
322330
headers: response.headers,
323331
});

‎packages/astro/src/i18n/middleware.ts

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
redirectToDefaultLocale,
99
redirectToFallback,
1010
requestHasLocale,
11+
requestIs404Or500,
1112
} from './index.js';
1213

1314
export function createI18nMiddleware(
@@ -69,6 +70,11 @@ export function createI18nMiddleware(
6970
return response;
7071
}
7172

73+
// 404 and 500 are **known** routes (users can have their custom pages), so we need to let them be
74+
if (requestIs404Or500(context.request, base)) {
75+
return response;
76+
}
77+
7278
const { currentLocale } = context;
7379

7480
switch (i18n.strategy) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<html>
2+
<head><title>Error</title></head>
3+
<body>Unexpected error.</body>
4+
</html>

‎packages/astro/test/i18n-routing-manual-with-default-middleware.test.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe('Dev server manual routing', () => {
2626
const response = await fixture.fetch('/blog');
2727
const text = await response.text();
2828
assert.equal(response.status, 404);
29-
assert.equal(text.includes('Blog should not render'), false);
29+
assert.match(text, /Blog should not render/);
3030
});
3131

3232
it('should return a 200 because the custom middleware allows it', async () => {
@@ -83,7 +83,8 @@ describe('SSR manual routing', () => {
8383
let request = new Request('http://example.com/blog');
8484
let response = await app.render(request);
8585
assert.equal(response.status, 404);
86-
assert.equal((await response.text()).includes('Blog should not render'), false);
86+
const text = await response.text();
87+
assert.match(text, /Blog should not render/);
8788
});
8889

8990
it('should return a 200 because the custom middleware allows it', async () => {

‎packages/astro/test/i18n-routing.test.js

+10
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,16 @@ describe('[SSG] i18n routing', () => {
580580
assert.equal($('body').text().includes('Lo siento'), true);
581581
});
582582

583+
it('should create a custom 404.html and 505.html', async () => {
584+
let html = await fixture.readFile('/404.html');
585+
let $ = cheerio.load(html);
586+
assert.equal($('body').text().includes("Can't find the page you're looking for."), true);
587+
588+
html = await fixture.readFile('/500.html');
589+
$ = cheerio.load(html);
590+
assert.equal($('body').text().includes('Unexpected error.'), true);
591+
});
592+
583593
it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => {
584594
try {
585595
await fixture.readFile('/it/start/index.html');

0 commit comments

Comments
 (0)
Please sign in to comment.