diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/docusaurus.config.js b/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/docusaurus.config.js
index d048d2caf5..b6b686f517 100644
--- a/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/docusaurus.config.js
+++ b/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/docusaurus.config.js
@@ -11,6 +11,10 @@ module.exports = {
url: 'https://your-docusaurus-site.example.com',
baseUrl: '/',
favicon: 'img/favicon.ico',
+ i18n: {
+ defaultLocale: 'en',
+ locales: ['en', 'fr'],
+ },
markdown: {
parseFrontMatter: async (params) => {
const result = await params.defaultParseFrontMatter(params);
diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/src/pages/typescript.fr.tsx b/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/src/pages/typescript.fr.tsx
new file mode 100644
index 0000000000..96e86b6afd
--- /dev/null
+++ b/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/src/pages/typescript.fr.tsx
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import Head from '@docusaurus/Head';
+
+export default class Home extends React.Component {
+ render() {
+ return (
+
+
+
translated Hello
+
+
translated TypeScript...
+
+ );
+ }
+}
diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap
index fc5fa21967..f082b1028e 100644
--- a/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap
+++ b/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap
@@ -69,7 +69,7 @@ exports[`docusaurus-plugin-content-pages loads simple pages with french translat
},
{
"permalink": "/fr/typescript",
- "source": "@site/src/pages/typescript.tsx",
+ "source": "@site/src/pages/typescript.fr.tsx",
"type": "jsx",
},
{
diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts
index a4707110f2..01b0d0d5cf 100644
--- a/packages/docusaurus-plugin-content-pages/src/index.ts
+++ b/packages/docusaurus-plugin-content-pages/src/index.ts
@@ -13,7 +13,6 @@ import {
aliasedSitePath,
docuHash,
getPluginI18nPath,
- getFolderContainingFile,
addTrailingPathSeparator,
Globby,
createAbsoluteFilePathMatcher,
@@ -22,6 +21,7 @@ import {
parseMarkdownFile,
isUnlisted,
isDraft,
+ findAsyncSequential,
} from '@docusaurus/utils';
import {validatePageFrontMatter} from './frontMatter';
@@ -38,6 +38,48 @@ export function getContentPathList(contentPaths: PagesContentPaths): string[] {
return [contentPaths.contentPathLocalized, contentPaths.contentPath];
}
+async function getLocalizedSource({
+ relativeSource,
+ contentPaths,
+ locale,
+}: {
+ relativeSource: string;
+ contentPaths: PagesContentPaths;
+ locale: string;
+}) {
+ const {name, dir, ext} = path.parse(relativeSource);
+
+ // Lookup in localized folder in priority
+ const possibleSources = getContentPathList(contentPaths).flatMap(
+ (contentPath) => [
+ path.join(contentPath, dir, `${name}.${locale}${ext}`),
+ path.join(contentPath, relativeSource),
+ ],
+ );
+
+ const localizedSource = await findAsyncSequential(
+ possibleSources,
+ fs.pathExists,
+ );
+
+ if (!localizedSource) {
+ throw new Error('unexpected');
+ }
+
+ return localizedSource;
+}
+
+function filterLocaleExtensionFiles(
+ files: string[],
+ locales: string[],
+): string[] {
+ const localeExtensions = locales.map((locale) => `.${locale}`);
+ return files.filter((file) => {
+ const {name} = path.parse(file);
+ return !localeExtensions.includes(path.extname(name));
+ });
+}
+
const isMarkdownSource = (source: string) =>
source.endsWith('.md') || source.endsWith('.mdx');
@@ -62,6 +104,14 @@ export default function pluginContentPages(
);
const dataDir = path.join(pluginDataDirRoot, options.id ?? DEFAULT_PLUGIN_ID);
+ async function getPageFiles() {
+ const files = await Globby(options.include, {
+ cwd: contentPaths.contentPath,
+ ignore: options.exclude,
+ });
+ return filterLocaleExtensionFiles(files, context.i18n.locales);
+ }
+
return {
name: 'docusaurus-plugin-content-pages',
@@ -73,28 +123,21 @@ export default function pluginContentPages(
},
async loadContent() {
- const {include} = options;
-
if (!(await fs.pathExists(contentPaths.contentPath))) {
return null;
}
const {baseUrl} = siteConfig;
- const pagesFiles = await Globby(include, {
- cwd: contentPaths.contentPath,
- ignore: options.exclude,
- });
+ const pagesFiles = await getPageFiles();
async function processPageSourceFile(
relativeSource: string,
): Promise {
- // Lookup in localized folder in priority
- const contentPath = await getFolderContainingFile(
- getContentPathList(contentPaths),
+ const source = await getLocalizedSource({
relativeSource,
- );
-
- const source = path.join(contentPath, relativeSource);
+ contentPaths,
+ locale: context.i18n.currentLocale,
+ });
const aliasedSourcePath = aliasedSitePath(source, siteDir);
const permalink = normalizeUrl([
baseUrl,
diff --git a/website/_dogfooding/_pages tests/i18n/index.fr.md b/website/_dogfooding/_pages tests/i18n/index.fr.md
new file mode 100644
index 0000000000..4917f6b55f
--- /dev/null
+++ b/website/_dogfooding/_pages tests/i18n/index.fr.md
@@ -0,0 +1,3 @@
+# Page i18n test
+
+French version
diff --git a/website/_dogfooding/_pages tests/i18n/index.md b/website/_dogfooding/_pages tests/i18n/index.md
new file mode 100644
index 0000000000..3d23cbe7b9
--- /dev/null
+++ b/website/_dogfooding/_pages tests/i18n/index.md
@@ -0,0 +1,3 @@
+# Page i18n test
+
+English version
diff --git a/website/_dogfooding/_pages tests/index.mdx b/website/_dogfooding/_pages tests/index.mdx
index 4f7c2889bf..851eebb038 100644
--- a/website/_dogfooding/_pages tests/index.mdx
+++ b/website/_dogfooding/_pages tests/index.mdx
@@ -26,6 +26,7 @@ import Readme from "../README.mdx"
### Other tests
- [React 18](/tests/pages/react-18)
+- [i18n](/tests/pages/i18n)
- [Crash test](/tests/pages/crashTest)
- [Code block tests](/tests/pages/code-block-tests)
- [Link tests](/tests/pages/link-tests)