Skip to content

Commit

Permalink
fix(i18n): allow to create 404.html and 500.html (#11062)
Browse files Browse the repository at this point in the history
* fix(i18n): allow to create 404.html and 500.html

* Update packages/astro/src/i18n/index.ts

Co-authored-by: Florian Lefebvre <[email protected]>

* Update .changeset/lazy-rockets-raise.md

* chore: use better matching

* fix linting

---------

Co-authored-by: Florian Lefebvre <[email protected]>
  • Loading branch information
ematipico and florian-lefebvre authored May 16, 2024
1 parent 3a0c02a commit 16f12e4
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/lazy-rockets-raise.md
Original file line number Diff line number Diff line change
@@ -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
10 changes: 9 additions & 1 deletion packages/astro/src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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('/');
Expand Down Expand Up @@ -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,
});
Expand Down
6 changes: 6 additions & 0 deletions packages/astro/src/i18n/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
redirectToDefaultLocale,
redirectToFallback,
requestHasLocale,
requestIs404Or500,
} from './index.js';

export function createI18nMiddleware(
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<html>
<head><title>Error</title></head>
<body>Unexpected error.</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down Expand Up @@ -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 () => {
Expand Down
10 changes: 10 additions & 0 deletions packages/astro/test/i18n-routing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down

0 comments on commit 16f12e4

Please sign in to comment.