diff --git a/packages/docusaurus-module-type-aliases/src/index.d.ts b/packages/docusaurus-module-type-aliases/src/index.d.ts index 725004638f51..72228dd6f009 100644 --- a/packages/docusaurus-module-type-aliases/src/index.d.ts +++ b/packages/docusaurus-module-type-aliases/src/index.d.ts @@ -64,7 +64,14 @@ declare module '@generated/i18n' { defaultLocale: string; locales: [string, ...string[]]; currentLocale: string; - localeConfigs: Record; + localeConfigs: Record< + string, + { + label: string; + direction: string; + htmlLang: string; + } + >; }; export = i18n; } diff --git a/packages/docusaurus-theme-classic/src/theme/LayoutHead/index.tsx b/packages/docusaurus-theme-classic/src/theme/LayoutHead/index.tsx index 2a4edcf15a2b..5e91606c75db 100644 --- a/packages/docusaurus-theme-classic/src/theme/LayoutHead/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/LayoutHead/index.tsx @@ -25,7 +25,7 @@ import {useLocation} from '@docusaurus/router'; // See https://github.com/facebook/docusaurus/issues/3317 function AlternateLangHeaders(): JSX.Element { const { - i18n: {defaultLocale, locales}, + i18n: {defaultLocale, localeConfigs}, } = useDocusaurusContext(); const alternatePageUtils = useAlternatePageUtils(); @@ -33,7 +33,7 @@ function AlternateLangHeaders(): JSX.Element { // See https://www.searchviu.com/en/multiple-hreflang-tags-one-url/ return ( - {locales.map((locale) => ( + {Object.entries(localeConfigs).map(([locale, {htmlLang}]) => ( ))} diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index e0ecf67cd9bb..d2fe18dab056 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -120,6 +120,7 @@ export type TranslationFiles = TranslationFile[]; export type I18nLocaleConfig = { label: string; + htmlLang: string; direction: string; }; diff --git a/packages/docusaurus/src/server/__tests__/i18n.test.ts b/packages/docusaurus/src/server/__tests__/i18n.test.ts index b45f11bc6acc..399bd928bf83 100644 --- a/packages/docusaurus/src/server/__tests__/i18n.test.ts +++ b/packages/docusaurus/src/server/__tests__/i18n.test.ts @@ -40,38 +40,47 @@ describe('defaultLocaleConfig', () => { expect(getDefaultLocaleConfig('fr')).toEqual({ label: canComputeLabel ? 'Français' : 'fr', direction: 'ltr', + htmlLang: 'fr', }); expect(getDefaultLocaleConfig('fr-FR')).toEqual({ label: canComputeLabel ? 'Français (France)' : 'fr-FR', direction: 'ltr', + htmlLang: 'fr-FR', }); expect(getDefaultLocaleConfig('en')).toEqual({ label: canComputeLabel ? 'English' : 'en', direction: 'ltr', + htmlLang: 'en', }); expect(getDefaultLocaleConfig('en-US')).toEqual({ label: canComputeLabel ? 'American English' : 'en-US', direction: 'ltr', + htmlLang: 'en-US', }); expect(getDefaultLocaleConfig('zh')).toEqual({ label: canComputeLabel ? '中文' : 'zh', direction: 'ltr', + htmlLang: 'zh', }); expect(getDefaultLocaleConfig('zh-CN')).toEqual({ label: canComputeLabel ? '中文(中国)' : 'zh-CN', direction: 'ltr', + htmlLang: 'zh-CN', }); expect(getDefaultLocaleConfig('en-US')).toEqual({ label: canComputeLabel ? 'American English' : 'en-US', direction: 'ltr', + htmlLang: 'en-US', }); expect(getDefaultLocaleConfig('fa')).toEqual({ label: canComputeLabel ? 'فارسی' : 'fa', direction: 'rtl', + htmlLang: 'fa', }); expect(getDefaultLocaleConfig('fa-IR')).toEqual({ label: canComputeLabel ? 'فارسی (ایران)' : 'fa-IR', direction: 'rtl', + htmlLang: 'fa-IR', }); }); }); @@ -156,7 +165,7 @@ describe('loadI18n', () => { locales: ['en', 'fr', 'de'], currentLocale: 'de', localeConfigs: { - fr: {label: 'Français', direction: 'ltr'}, + fr: {label: 'Français', direction: 'ltr', htmlLang: 'fr'}, en: getDefaultLocaleConfig('en'), de: getDefaultLocaleConfig('de'), }, diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index 8d9ad089f985..420315ff0da9 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -96,6 +96,7 @@ const PresetSchema = Joi.alternatives().try( const LocaleConfigSchema = Joi.object({ label: Joi.string(), + htmlLang: Joi.string(), direction: Joi.string().equal('ltr', 'rtl').default('ltr'), }); diff --git a/packages/docusaurus/src/server/i18n.ts b/packages/docusaurus/src/server/i18n.ts index b7d1814e26de..6a847d6e9b8a 100644 --- a/packages/docusaurus/src/server/i18n.ts +++ b/packages/docusaurus/src/server/i18n.ts @@ -24,6 +24,7 @@ export function getDefaultLocaleConfig(locale: string): I18nLocaleConfig { return { label: getDefaultLocaleLabel(locale), direction: getLangDir(locale), + htmlLang: locale, }; }