diff --git a/.changeset/stupid-seas-roll.md b/.changeset/stupid-seas-roll.md new file mode 100644 index 0000000000..9fd933b596 --- /dev/null +++ b/.changeset/stupid-seas-roll.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes an issue where `Astro.currentLocale` wasn't incorrectly computed when the `defaultLocale` belonged to a custom locale path. diff --git a/packages/astro/src/actions/runtime/middleware.ts b/packages/astro/src/actions/runtime/middleware.ts index c12b64b6d5..bca110652d 100644 --- a/packages/astro/src/actions/runtime/middleware.ts +++ b/packages/astro/src/actions/runtime/middleware.ts @@ -133,7 +133,6 @@ async function redirectWithResult({ if (!referer) { throw new Error('Internal: Referer unexpectedly missing from Action POST request.'); } - return context.redirect(referer); } diff --git a/packages/astro/src/core/middleware/index.ts b/packages/astro/src/core/middleware/index.ts index 56ce0b76c3..2ca8021266 100644 --- a/packages/astro/src/core/middleware/index.ts +++ b/packages/astro/src/core/middleware/index.ts @@ -31,6 +31,11 @@ export type CreateContext = { * A list of locales that are supported by the user */ userDefinedLocales?: string[]; + + /** + * User defined default locale + */ + defaultLocale: string; }; /** @@ -40,6 +45,7 @@ function createContext({ request, params = {}, userDefinedLocales = [], + defaultLocale = '', }: CreateContext): APIContext { let preferredLocale: string | undefined = undefined; let preferredLocaleList: string[] | undefined = undefined; @@ -75,7 +81,7 @@ function createContext({ return (preferredLocaleList ??= computePreferredLocaleList(request, userDefinedLocales)); }, get currentLocale(): string | undefined { - return (currentLocale ??= computeCurrentLocale(route, userDefinedLocales)); + return (currentLocale ??= computeCurrentLocale(route, userDefinedLocales, defaultLocale)); }, url, get clientAddress() { diff --git a/packages/astro/src/core/render-context.ts b/packages/astro/src/core/render-context.ts index 1658f6c235..8850da132e 100644 --- a/packages/astro/src/core/render-context.ts +++ b/packages/astro/src/core/render-context.ts @@ -535,8 +535,8 @@ export class RenderContext { // and url.pathname to pass Astro.currentLocale tests. // A single call with `routeData.pathname ?? routeData.route` as the pathname still fails. return (this.#currentLocale ??= - computeCurrentLocale(routeData.route, locales) ?? - computeCurrentLocale(url.pathname, locales) ?? + computeCurrentLocale(routeData.route, locales, defaultLocale) ?? + computeCurrentLocale(url.pathname, locales, defaultLocale) ?? fallbackTo); } diff --git a/packages/astro/src/i18n/utils.ts b/packages/astro/src/i18n/utils.ts index 47addeacba..c79c66612d 100644 --- a/packages/astro/src/i18n/utils.ts +++ b/packages/astro/src/i18n/utils.ts @@ -148,7 +148,11 @@ export function computePreferredLocaleList(request: Request, locales: Locales): return result; } -export function computeCurrentLocale(pathname: string, locales: Locales): undefined | string { +export function computeCurrentLocale( + pathname: string, + locales: Locales, + defaultLocale: string, +): string | undefined { for (const segment of pathname.split('/')) { for (const locale of locales) { if (typeof locale === 'string') { @@ -171,6 +175,19 @@ export function computeCurrentLocale(pathname: string, locales: Locales): undefi } } } + // If we didn't exit, it's probably because we don't have any code/locale in the URL. + // We use the default locale. + for (const locale of locales) { + if (typeof locale === 'string') { + if (locale === defaultLocale) { + return locale; + } + } else { + if (locale.path === defaultLocale) { + return locale.codes.at(0); + } + } + } } export type RoutingStrategies = diff --git a/packages/astro/test/fixtures/i18n-routing/astro.config.mjs b/packages/astro/test/fixtures/i18n-routing/astro.config.mjs index 8868d2b1f6..8d9a83e8de 100644 --- a/packages/astro/test/fixtures/i18n-routing/astro.config.mjs +++ b/packages/astro/test/fixtures/i18n-routing/astro.config.mjs @@ -2,7 +2,7 @@ import { defineConfig} from "astro/config"; export default defineConfig({ i18n: { - defaultLocale: 'en', + defaultLocale: 'spanish', locales: [ 'en', 'pt', diff --git a/packages/astro/test/i18n-routing.test.js b/packages/astro/test/i18n-routing.test.js index ddb31762f4..18b8fe6705 100644 --- a/packages/astro/test/i18n-routing.test.js +++ b/packages/astro/test/i18n-routing.test.js @@ -1106,7 +1106,7 @@ describe('[SSG] i18n routing', () => { it('should return the default locale', async () => { const html = await fixture.readFile('/current-locale/index.html'); - assert.equal(html.includes('Current Locale: en'), true); + assert.equal(html.includes('Current Locale: es'), true); }); it('should return the default locale when rendering a route with spread operator', async () => { @@ -1121,7 +1121,7 @@ describe('[SSG] i18n routing', () => { it('should return the default locale when a route is dynamic', async () => { const html = await fixture.readFile('/dynamic/lorem/index.html'); - assert.equal(html.includes('Current Locale: en'), true); + assert.equal(html.includes('Current Locale: es'), true); }); it('should returns the correct locale when requesting a locale via path', async () => { @@ -1701,7 +1701,7 @@ describe('[SSR] i18n routing', () => { let request = new Request('http://example.com/current-locale', {}); let response = await app.render(request); assert.equal(response.status, 200); - assert.equal((await response.text()).includes('Current Locale: en'), true); + assert.equal((await response.text()).includes('Current Locale: es'), true); }); it('should return the default locale when rendering a route with spread operator', async () => { @@ -1722,7 +1722,7 @@ describe('[SSR] i18n routing', () => { let request = new Request('http://example.com/dynamic/lorem', {}); let response = await app.render(request); assert.equal(response.status, 200); - assert.equal((await response.text()).includes('Current Locale: en'), true); + assert.equal((await response.text()).includes('Current Locale: es'), true); }); });