diff --git a/.changeset/old-pugs-jog.md b/.changeset/old-pugs-jog.md new file mode 100644 index 0000000000000..8b5aa217edd17 --- /dev/null +++ b/.changeset/old-pugs-jog.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Fixes a case where the i18n fallback faild to correctly redirect to the index when the fallback is enabled in SSR diff --git a/packages/astro/src/i18n/index.ts b/packages/astro/src/i18n/index.ts index 32cd24f9cff0d..b8114019bdcf0 100644 --- a/packages/astro/src/i18n/index.ts +++ b/packages/astro/src/i18n/index.ts @@ -343,6 +343,7 @@ export function redirectToFallback({ locales, defaultLocale, strategy, + base, }: MiddlewarePayload) { return function (context: APIContext, response: Response): Response { if (response.status >= 300 && fallback) { @@ -370,7 +371,11 @@ export function redirectToFallback({ // If a locale falls back to the default locale, we want to **remove** the locale because // the default locale doesn't have a prefix if (pathFallbackLocale === defaultLocale && strategy === 'pathname-prefix-other-locales') { - newPathname = context.url.pathname.replace(`/${urlLocale}`, ``); + if (context.url.pathname.includes(`${base}`)) { + newPathname = context.url.pathname.replace(`/${urlLocale}`, ``); + } else { + newPathname = context.url.pathname.replace(`/${urlLocale}`, `/`); + } } else { newPathname = context.url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`); } diff --git a/packages/astro/test/i18n-routing.test.js b/packages/astro/test/i18n-routing.test.js index 6e1503819b402..edbf74c5260bf 100644 --- a/packages/astro/test/i18n-routing.test.js +++ b/packages/astro/test/i18n-routing.test.js @@ -1871,3 +1871,36 @@ describe('i18n routing does not break assets and endpoints', () => { }); }); }); + +describe.only('SSR fallback from missing locale index to default locale index', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + let app; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing-prefix-other-locales/', + output: 'server', + adapter: testAdapter(), + i18n: { + defaultLocale: 'en', + locales: ['en', 'fr'], + routing: { + prefixDefaultLocale: false, + }, + fallback: { + fr: 'en', + }, + }, + }); + await fixture.build(); + app = await fixture.loadTestAdapterApp(); + }); + + it.only('should correctly redirect', async () => { + let request = new Request('http://example.com/fr'); + let response = await app.render(request); + assert.equal(response.status, 302); + assert.equal(response.headers.get('location'), '/'); + }); +});