From 6bf21d215c232fbff8eefda72506b075659ca9c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Thu, 22 Feb 2024 17:06:12 +0100 Subject: [PATCH] fix(core): fix default i18n calendar used, infer it from locale if possible (#9878) --- .../src/server/__tests__/i18n.test.ts | 4 +-- packages/docusaurus/src/server/i18n.ts | 27 +++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/docusaurus/src/server/__tests__/i18n.test.ts b/packages/docusaurus/src/server/__tests__/i18n.test.ts index e846f942f527..205dc7b05c69 100644 --- a/packages/docusaurus/src/server/__tests__/i18n.test.ts +++ b/packages/docusaurus/src/server/__tests__/i18n.test.ts @@ -81,7 +81,7 @@ describe('defaultLocaleConfig', () => { label: 'فارسی', direction: 'rtl', htmlLang: 'fa', - calendar: 'gregory', + calendar: 'persian', path: 'fa', }); expect(getDefaultLocaleConfig('fa-IR')).toEqual({ @@ -89,7 +89,7 @@ describe('defaultLocaleConfig', () => { label: 'فارسی (ایران)', direction: 'rtl', htmlLang: 'fa-IR', - calendar: 'gregory', + calendar: 'persian', path: 'fa-IR', }); expect(getDefaultLocaleConfig('en-US-u-ca-buddhist')).toEqual({ diff --git a/packages/docusaurus/src/server/i18n.ts b/packages/docusaurus/src/server/i18n.ts index 92292f2ec5f7..21f1b5ebd3b6 100644 --- a/packages/docusaurus/src/server/i18n.ts +++ b/packages/docusaurus/src/server/i18n.ts @@ -19,13 +19,36 @@ function getDefaultLocaleLabel(locale: string) { ); } +function getDefaultCalendar(localeStr: string) { + const locale = new Intl.Locale(localeStr); + + // If the locale name includes -u-ca-xxx the calendar will be defined + if (locale.calendar) { + return locale.calendar; + } + + // Not well-supported but server code can infer a calendar from the locale + // See https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/getCalendars + // See https://caniuse.com/mdn-javascript_builtins_intl_locale_getcalendars + const calendars = + // @ts-expect-error: new std method (Bun/JSC/WebKit) + locale.getCalendars?.() ?? + // @ts-expect-error: non-std attribute (V8/Chromium/Node) + locale.calendars; + + if (calendars instanceof Array && calendars[0]) { + return calendars[0]; + } + + return 'gregory'; +} + export function getDefaultLocaleConfig(locale: string): I18nLocaleConfig { return { label: getDefaultLocaleLabel(locale), direction: getLangDir(locale), htmlLang: locale, - // If the locale name includes -u-ca-xxx the calendar will be defined - calendar: new Intl.Locale(locale).calendar ?? 'gregory', + calendar: getDefaultCalendar(locale), path: locale, }; }