summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/tough-socks-change.md5
-rw-r--r--packages/astro/src/i18n/middleware.ts8
-rw-r--r--packages/astro/test/fixtures/i18n-routing/src/pages/endurance.astro9
-rw-r--r--packages/astro/test/i18n-routing.test.js64
4 files changed, 85 insertions, 1 deletions
diff --git a/.changeset/tough-socks-change.md b/.changeset/tough-socks-change.md
new file mode 100644
index 000000000..1f6b2762e
--- /dev/null
+++ b/.changeset/tough-socks-change.md
@@ -0,0 +1,5 @@
+---
+"astro": patch
+---
+
+Fixes a bug where routes with a name that start with the name of the `i18n.defaultLocale` were incorrectly returning a 404 response.
diff --git a/packages/astro/src/i18n/middleware.ts b/packages/astro/src/i18n/middleware.ts
index 5e9f17a6a..1c05a956b 100644
--- a/packages/astro/src/i18n/middleware.ts
+++ b/packages/astro/src/i18n/middleware.ts
@@ -65,7 +65,13 @@ export function createI18nMiddleware(
};
const prefixOtherLocales = (url: URL, response: Response): Response | undefined => {
- const pathnameContainsDefaultLocale = url.pathname.includes(`/${i18n.defaultLocale}`);
+ let pathnameContainsDefaultLocale = false;
+ for (const segment of url.pathname.split('/')) {
+ if (normalizeTheLocale(segment) === normalizeTheLocale(i18n.defaultLocale)) {
+ pathnameContainsDefaultLocale = true;
+ break;
+ }
+ }
if (pathnameContainsDefaultLocale) {
const newLocation = url.pathname.replace(`/${i18n.defaultLocale}`, '');
response.headers.set('Location', newLocation);
diff --git a/packages/astro/test/fixtures/i18n-routing/src/pages/endurance.astro b/packages/astro/test/fixtures/i18n-routing/src/pages/endurance.astro
new file mode 100644
index 000000000..8be48a732
--- /dev/null
+++ b/packages/astro/test/fixtures/i18n-routing/src/pages/endurance.astro
@@ -0,0 +1,9 @@
+<html>
+<head>
+ <title>Astro</title>
+</head>
+<body>
+Endurance
+</body>
+</html>
+
diff --git a/packages/astro/test/i18n-routing.test.js b/packages/astro/test/i18n-routing.test.js
index 2e8256cac..da22f0311 100644
--- a/packages/astro/test/i18n-routing.test.js
+++ b/packages/astro/test/i18n-routing.test.js
@@ -59,6 +59,30 @@ describe('astro:i18n virtual module', () => {
});
});
describe('[DEV] i18n routing', () => {
+ describe('should render a page that stars with a locale but it is a page', () => {
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+ /** @type {import('./test-utils').DevServer} */
+ let devServer;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/i18n-routing/',
+ });
+ devServer = await fixture.startDevServer();
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ it('renders the page', async () => {
+ const response = await fixture.fetch('/endurance');
+ expect(response.status).to.equal(200);
+ expect(await response.text()).includes('Endurance');
+ });
+ });
+
describe('i18n routing', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;
@@ -1005,6 +1029,23 @@ describe('[SSG] i18n routing', () => {
});
});
+ describe('should render a page that stars with a locale but it is a page', () => {
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/i18n-routing/',
+ });
+ await fixture.build();
+ });
+
+ it('renders the page', async () => {
+ const html = await fixture.readFile('/endurance/index.html');
+ expect(html).includes('Endurance');
+ });
+ });
+
describe('current locale', () => {
describe('with [prefix-other-locales]', () => {
/** @type {import('./test-utils').Fixture} */
@@ -1068,6 +1109,29 @@ describe('[SSG] i18n routing', () => {
});
describe('[SSR] i18n routing', () => {
let app;
+
+ describe('should render a page that stars with a locale but it is a page', () => {
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/i18n-routing/',
+ output: 'server',
+ adapter: testAdapter(),
+ });
+ await fixture.build();
+ app = await fixture.loadTestAdapterApp();
+ });
+
+ it('renders the page', async () => {
+ let request = new Request('http://example.com/endurance');
+ let response = await app.render(request);
+ expect(response.status).to.equal(200);
+ expect(await response.text()).includes('Endurance');
+ });
+ });
+
describe('default', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;