feat(i18n): add multilingual support for documentation with Chinese and English content

This commit is contained in:
HouYunFei
2026-08-05 14:41:42 +08:00
parent 5a7116f924
commit ec82958f7c
82 changed files with 2400 additions and 1473 deletions
+9
View File
@@ -8,6 +8,7 @@ import {
MarkdownCopyButton,
ViewOptionsPopover,
} from 'fumadocs-ui/layouts/docs/page';
import { localizePath } from './i18n';
export type DocPageData = (typeof source)['$inferPage'];
@@ -38,8 +39,16 @@ export function DocPageContent({ page }: { page: DocPageData }) {
}
export function getDocPageMetadata(page: DocPageData): Metadata {
const path = `/docs/${page.slugs.join('/')}`;
return {
title: page.data.title,
description: page.data.description,
alternates: {
languages: {
en: localizePath('en', path),
'zh-CN': localizePath('zh-CN', path),
},
},
};
}
+15
View File
@@ -0,0 +1,15 @@
import { defineI18n } from 'fumadocs-core/i18n';
export type Locale = 'en' | 'zh-CN';
export const i18n = defineI18n({
defaultLanguage: 'en',
languages: ['en', 'zh-CN'],
parser: 'dot',
hideLocale: 'default-locale',
fallbackLanguage: null,
});
export function localizePath(locale: string, path: string) {
return locale === i18n.defaultLanguage ? path : `/${locale}${path}`;
}
+46 -5
View File
@@ -1,11 +1,52 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
import { appName, gitConfig } from './shared';
import { appNames, gitConfig } from './shared';
import { ArrowUpRight } from 'lucide-react';
import { i18n } from './i18n';
import { uiTranslations } from 'fumadocs-ui/i18n';
const githubUrl = `https://github.com/${gitConfig.user}/${gitConfig.repo}`;
const qqUrl = 'https://qm.qq.com/q/DFnKzZ807u';
export function baseOptions(): BaseLayoutProps {
export const translations = i18n.translations().extend(uiTranslations()).add('ui', {
en: {
displayName: 'English',
},
'zh-CN': {
displayName: '简体中文',
search: '搜索文档',
searchNoResult: '没有找到结果',
searchOpen: '打开搜索',
searchClose: '关闭搜索',
toc: '本页目录',
tocNoHeadings: '本页没有标题',
tocInline: '本页内容',
chooseLanguage: '选择语言',
nextPage: '下一页',
previousPage: '上一页',
chooseTheme: '选择主题',
themeToggle: '切换主题',
themeLight: '浅色',
themeDark: '深色',
themeSystem: '跟随系统',
codeBlockCopy: '复制代码',
codeBlockCopied: '已复制',
menuToggle: '切换菜单',
pageActionsCopyMarkdown: '复制 Markdown',
pageActionsOpen: '打开',
pageActionsOpenGitHub: '在 GitHub 中打开',
pageActionsViewMarkdown: '查看 Markdown',
sidebarOpen: '打开侧边栏',
sidebarCollapse: '收起侧边栏',
notFoundTitle: '页面不存在',
notFoundDescription: '你访问的页面不存在。',
notFoundLink: '返回首页',
},
});
export function baseOptions(locale: string): BaseLayoutProps {
const chinese = locale === 'zh-CN';
const appName = appNames[locale as keyof typeof appNames];
return {
nav: {
title: (
@@ -17,14 +58,14 @@ export function baseOptions(): BaseLayoutProps {
},
links: [
{
text: '文档导航',
url: '/docs/overview/quick-start',
text: chinese ? '文档导航' : 'Documentation',
url: `${chinese ? '/zh-CN' : ''}/docs/overview/quick-start`,
on: 'nav',
},
{
text: (
<span className="inline-flex items-center gap-1.5">
<span>线</span>
<span>{chinese ? '在线体验' : 'Live Demo'}</span>
<ArrowUpRight className="size-4" />
</span>
),
+4 -1
View File
@@ -1,4 +1,7 @@
export const appName = '无限画布';
export const appNames = {
en: 'Infinite Canvas',
'zh-CN': '无限画布',
};
export const docsRoute = '/docs';
export const docsContentRoute = '/llms.mdx/docs';
+4 -1
View File
@@ -1,20 +1,23 @@
import { docs } from 'collections/server';
import { loader } from 'fumadocs-core/source';
import { docsContentRoute, docsRoute } from './shared';
import { i18n } from './i18n';
// See https://fumadocs.dev/docs/headless/source-api for more info
export const source = loader({
baseUrl: docsRoute,
source: docs.toFumadocsSource(),
i18n,
plugins: [],
});
export function getPageMarkdownUrl(page: (typeof source)['$inferPage']) {
const segments = [...page.slugs, 'content.md'];
const locale = page.locale === i18n.defaultLanguage ? '' : `?locale=${page.locale}`;
return {
segments,
url: `${docsContentRoute}/${segments.join('/')}`,
url: `${docsContentRoute}/${segments.join('/')}${locale}`,
};
}