summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/ninety-nights-hug.md7
-rw-r--r--packages/astro/src/i18n/index.ts13
-rw-r--r--packages/astro/src/i18n/utils.ts19
-rw-r--r--packages/astro/test/fixtures/i18n-routing-redirect-preferred-language/astro.config.mjs9
-rw-r--r--packages/astro/test/i18n-routing.test.js18
5 files changed, 51 insertions, 15 deletions
diff --git a/.changeset/ninety-nights-hug.md b/.changeset/ninety-nights-hug.md
new file mode 100644
index 000000000..aa4017497
--- /dev/null
+++ b/.changeset/ninety-nights-hug.md
@@ -0,0 +1,7 @@
+---
+'astro': patch
+---
+
+Fixes a bug where the functions `Astro.preferredLocale` and `Astro.preferredLocaleList` would return the incorrect locales
+when the Astro configuration specifies a list of `codes`. Before, the functions would return the `path`, instead now the functions
+return a list built from `codes`.
diff --git a/packages/astro/src/i18n/index.ts b/packages/astro/src/i18n/index.ts
index 73b33fa60..10d451b22 100644
--- a/packages/astro/src/i18n/index.ts
+++ b/packages/astro/src/i18n/index.ts
@@ -229,6 +229,18 @@ export function normalizeTheLocale(locale: string): string {
* Returns an array of only locales, by picking the `code`
* @param locales
*/
+export function getAllCodes(locales: Locales): string[] {
+ const result: string[] = [];
+ for (const loopLocale of locales) {
+ if (typeof loopLocale === 'string') {
+ result.push(loopLocale);
+ } else {
+ result.push(...loopLocale.codes);
+ }
+ }
+ return result
+}
+
export function toCodes(locales: Locales): string[] {
return locales.map((loopLocale) => {
if (typeof loopLocale === 'string') {
@@ -239,6 +251,7 @@ export function toCodes(locales: Locales): string[] {
});
}
+
/**
* It returns the array of paths
* @param locales
diff --git a/packages/astro/src/i18n/utils.ts b/packages/astro/src/i18n/utils.ts
index 18a6f8dca..ed8ec147d 100644
--- a/packages/astro/src/i18n/utils.ts
+++ b/packages/astro/src/i18n/utils.ts
@@ -1,6 +1,6 @@
import type { SSRManifest } from '../core/app/types.js';
import type { AstroConfig, Locales } from '../types/public/config.js';
-import { normalizeTheLocale, toCodes } from './index.js';
+import { normalizeTheLocale, getAllCodes } from './index.js';
type BrowserLocale = {
locale: string;
@@ -62,7 +62,7 @@ export function parseLocale(header: string): BrowserLocale[] {
}
function sortAndFilterLocales(browserLocaleList: BrowserLocale[], locales: Locales) {
- const normalizedLocales = toCodes(locales).map(normalizeTheLocale);
+ const normalizedLocales = getAllCodes(locales).map(normalizeTheLocale);
return browserLocaleList
.filter((browserLocale) => {
if (browserLocale.locale !== '*') {
@@ -96,11 +96,13 @@ export function computePreferredLocale(request: Request, locales: Locales): stri
if (typeof currentLocale === 'string') {
if (normalizeTheLocale(currentLocale) === normalizeTheLocale(firstResult.locale)) {
result = currentLocale;
+ break;
}
} else {
for (const currentCode of currentLocale.codes) {
if (normalizeTheLocale(currentCode) === normalizeTheLocale(firstResult.locale)) {
- result = currentLocale.path;
+ result = currentCode;
+ break;
}
}
}
@@ -119,14 +121,7 @@ export function computePreferredLocaleList(request: Request, locales: Locales):
// SAFETY: bang operator is safe because checked by the previous condition
if (browserLocaleList.length === 1 && browserLocaleList.at(0)!.locale === '*') {
- return locales.map((locale) => {
- if (typeof locale === 'string') {
- return locale;
- } else {
- // SAFETY: codes is never empty
- return locale.codes.at(0)!;
- }
- });
+ return getAllCodes(locales);
} else if (browserLocaleList.length > 0) {
for (const browserLocale of browserLocaleList) {
for (const loopLocale of locales) {
@@ -137,7 +132,7 @@ export function computePreferredLocaleList(request: Request, locales: Locales):
} else {
for (const code of loopLocale.codes) {
if (code === browserLocale.locale) {
- result.push(loopLocale.path);
+ result.push(code);
}
}
}
diff --git a/packages/astro/test/fixtures/i18n-routing-redirect-preferred-language/astro.config.mjs b/packages/astro/test/fixtures/i18n-routing-redirect-preferred-language/astro.config.mjs
index 259b10d07..20e815540 100644
--- a/packages/astro/test/fixtures/i18n-routing-redirect-preferred-language/astro.config.mjs
+++ b/packages/astro/test/fixtures/i18n-routing-redirect-preferred-language/astro.config.mjs
@@ -4,7 +4,14 @@ export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: [
- 'en', 'pt', 'it'
+ 'en',
+ 'pt',
+ 'it',
+ {
+ path: "zh-Hant",
+ codes: ["zh-HK", "zh-TW"]
+ }
+
]
}
})
diff --git a/packages/astro/test/i18n-routing.test.js b/packages/astro/test/i18n-routing.test.js
index 473fc8817..a0a2eccfb 100644
--- a/packages/astro/test/i18n-routing.test.js
+++ b/packages/astro/test/i18n-routing.test.js
@@ -1701,6 +1701,20 @@ describe('[SSR] i18n routing', () => {
assert.equal(text.includes('Locale list: en, pt, it'), true);
});
+
+ it('should render the preferred locale when a locale is configured with codes', async () => {
+ let request = new Request('http://example.com/preferred-locale', {
+ headers: {
+ 'Accept-Language': 'es-SP;q=0.9,es;q=0.8,en-US;q=0.7,en;q=0.6',
+ },
+ });
+ let response = await app.render(request);
+ const text = await response.text();
+ assert.equal(response.status, 200);
+ assert.equal(text.includes('Locale: es-SP'), true);
+ assert.equal(text.includes('Locale list: es-SP, es, en'), true);
+ });
+
describe('in case the configured locales use underscores', () => {
before(async () => {
fixture = await loadFixture({
@@ -1751,8 +1765,8 @@ describe('[SSR] i18n routing', () => {
let response = await app.render(request);
const text = await response.text();
assert.equal(response.status, 200);
- assert.equal(text.includes('Locale: spanish'), true);
- assert.equal(text.includes('Locale list: spanish'), true);
+ assert.equal(text.includes('Locale: es'), true);
+ assert.equal(text.includes('Locale list: es'), true);
});
});
});