0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-27 22:19:04 -05:00

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>
This commit is contained in:
Emanuele Stoppa 2024-05-16 14:43:30 +01:00 committed by GitHub
parent 3a0c02ae03
commit 16f12e426e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 37 additions and 3 deletions

View file

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

View file

@ -19,6 +19,14 @@ export function requestHasLocale(locales: Locales) {
};
}
export function requestIs404Or500(request: Request, base = '') {
const url = new URL(request.url);
return (
url.pathname.startsWith(`${base}/404`) ||
url.pathname.startsWith(`${base}/500`)
);
}
// Checks if the pathname has any locale
export function pathHasLocale(path: string, locales: Locales): boolean {
const segments = path.split('/');
@ -317,7 +325,7 @@ export function notFound({ base, locales }: MiddlewarePayload) {
if (!(isRoot || pathHasLocale(url.pathname, locales))) {
if (response) {
response.headers.set(REROUTE_DIRECTIVE_HEADER, 'no');
return new Response(null, {
return new Response(response.body, {
status: 404,
headers: response.headers,
});

View file

@ -8,6 +8,7 @@ import {
redirectToDefaultLocale,
redirectToFallback,
requestHasLocale,
requestIs404Or500,
} from './index.js';
export function createI18nMiddleware(
@ -69,6 +70,11 @@ export function createI18nMiddleware(
return response;
}
// 404 and 500 are **known** routes (users can have their custom pages), so we need to let them be
if (requestIs404Or500(context.request, base)) {
return response;
}
const { currentLocale } = context;
switch (i18n.strategy) {

View file

@ -0,0 +1,4 @@
<html>
<head><title>Error</title></head>
<body>Unexpected error.</body>
</html>

View file

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

View file

@ -580,6 +580,16 @@ describe('[SSG] i18n routing', () => {
assert.equal($('body').text().includes('Lo siento'), true);
});
it('should create a custom 404.html and 505.html', async () => {
let html = await fixture.readFile('/404.html');
let $ = cheerio.load(html);
assert.equal($('body').text().includes("Can't find the page you're looking for."), true);
html = await fixture.readFile('/500.html');
$ = cheerio.load(html);
assert.equal($('body').text().includes('Unexpected error.'), true);
});
it("should NOT render the default locale if there isn't a fallback and the route is missing", async () => {
try {
await fixture.readFile('/it/start/index.html');