Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/docusaurus-module-type-aliases/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,14 @@ declare module '@generated/i18n' {
defaultLocale: string;
locales: [string, ...string[]];
currentLocale: string;
localeConfigs: Record<string, {label: string; direction: string}>;
localeConfigs: Record<
string,
{
label: string;
direction: string;
htmlLang: string;
}
>;
};
export = i18n;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@ 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();

// Note: it is fine to use both "x-default" and "en" to target the same url
// See https://www.searchviu.com/en/multiple-hreflang-tags-one-url/
return (
<Head>
{locales.map((locale) => (
{Object.entries(localeConfigs).map(([locale, {htmlLang}]) => (
<link
key={locale}
rel="alternate"
href={alternatePageUtils.createUrl({
locale,
fullyQualified: true,
})}
hrefLang={locale}
hrefLang={htmlLang}
/>
))}
<link
Expand Down Expand Up @@ -91,11 +91,7 @@ export default function LayoutHead(props: Props): JSX.Element {
const {title, description, image, keywords, searchMetadata} = props;
const faviconUrl = useBaseUrl(favicon);
const pageTitle = useTitleFormatter(title);

// See https://github.com/facebook/docusaurus/issues/3317#issuecomment-754661855
// const htmlLang = currentLocale.split('-')[0];
const htmlLang = currentLocale; // should we allow the user to override htmlLang with localeConfig?
const htmlDir = localeConfigs[currentLocale].direction;
const {htmlLang, direction: htmlDir} = localeConfigs[currentLocale];

return (
<>
Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus-types/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export type TranslationFiles = TranslationFile[];

export type I18nLocaleConfig = {
label: string;
htmlLang: string;
direction: string;
};

Expand Down
11 changes: 10 additions & 1 deletion packages/docusaurus/src/server/__tests__/i18n.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
});
});
});
Expand Down Expand Up @@ -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'),
},
Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus/src/server/configValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const PresetSchema = Joi.alternatives().try(

const LocaleConfigSchema = Joi.object({
label: Joi.string(),
htmlLang: Joi.string(),
direction: Joi.string().equal('ltr', 'rtl').default('ltr'),
});

Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus/src/server/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export function getDefaultLocaleConfig(locale: string): I18nLocaleConfig {
return {
label: getDefaultLocaleLabel(locale),
direction: getLangDir(locale),
htmlLang: locale,
};
}

Expand Down