Fumadocs
AI-перевод для Fumadocs с помощью Lingo.dev CLI
Что такое Fumadocs?
Fumadocs — это фреймворк для создания документации с открытым исходным кодом. Он предоставляет быстрый, типобезопасный сайт документации с встроенным поиском, поддержкой интернационализации и красивым пользовательским интерфейсом.
Что такое Lingo.dev CLI?
Lingo.dev — это платформа перевода на основе искусственного интеллекта. Lingo.dev CLI считывает исходные файлы, отправляет переводимый контент в крупные языковые модели и записывает переведенные файлы обратно в ваш проект.
О данном руководстве
В этом руководстве объясняется, как настроить Lingo.dev CLI в проекте документации Fumadocs. Вы узнаете, как создать проект с помощью Fumadocs, настроить процесс перевода и просмотреть результаты.
Шаг 1. Настройка проекта Fumadocs
-
Создайте новое приложение Fumadocs:
npm create fumadocs-app
-
Следуйте инструкциям для настройки проекта с предпочтительными параметрами.
-
Перейдите в каталог проекта:
cd <project-name>
Шаг 2. Настройка поддержки интернационализации
Fumadocs необходимо знать, какие языки будет поддерживать ваша документация. Вам нужно будет создать конфигурационные файлы, которые укажут Fumadocs, как обрабатывать несколько языков.
-
Создайте файл
lib/i18n.ts
, чтобы определить поддерживаемые языки:import { defineI18n } from 'fumadocs-core/i18n'; export const i18n = defineI18n({ defaultLanguage: 'en', languages: ['en', 'es'], parser: "dir", });
-
Обновите файл
lib/source.ts
, чтобы использовать настройки i18n:import { docs } from "@/.source"; import { loader } from "fumadocs-core/source"; import { i18n } from "@/lib/i18n"; // Подробнее см. https://fumadocs.vercel.app/docs/headless/source-api export const source = loader({ // назначает URL вашим страницам baseUrl: "/docs", source: docs.toFumadocsSource(), i18n, });
-
Создайте middleware для определения и перенаправления пользователей на основе их языковых предпочтений:
// middleware.ts import { createI18nMiddleware } from 'fumadocs-core/i18n/middleware'; import { i18n } from '@/lib/i18n'; export default createI18nMiddleware(i18n); export const config = { // Исключение для `/_next/` и `/api/` // Возможно, потребуется настроить для исключения статических ресурсов в папке `/public` matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], };
Шаг 3. Обновите структуру приложения для нескольких языков
-
Создайте каталог параметров языка в папке
app/
:mkdir app/[lang]
-
Переместите существующие страницы в каталог параметров языка:
app/docs/
→app/[lang]/docs/
app/(home)/
→app/[lang]/(home)/
-
Создайте файл
app/[lang]/layout.tsx
, чтобы обернуть все страницы, специфичные для языка:import { RootProvider } from "fumadocs-ui/provider"; import { defineI18nUI } from "fumadocs-ui/i18n"; import { i18n } from "@/lib/i18n"; const { provider } = defineI18nUI(i18n, { translations: { en: { displayName: "English", }, es: { displayName: "Español", }, }, }); export default async function RootLayout({ params, children, }: LayoutProps<"/[lang]">) { const lang = (await params).lang; return ( <html lang={lang}> <body> <RootProvider i18n={provider(lang)}>{children}</RootProvider> </body> </html> ); }
Шаг 4. Создайте общие параметры макета
-
Создайте файл
lib/layout.shared.tsx
для общих конфигураций макета:// lib/layout.shared.tsx import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared"; import { i18n } from "@/lib/i18n"; /** * Общие конфигурации макета * * вы можете настроить макеты индивидуально из: * Макет главной страницы: app/(home)/layout.tsx * Макет документации: app/docs/layout.tsx */ export function baseOptions(locale: string): BaseLayoutProps { return { i18n, nav: { title: ( <> <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" aria-label="Logo" > <circle cx={12} cy={12} r={12} fill="currentColor" /> </svg> My App </> ), }, // см. https://fumadocs.dev/docs/ui/navigation/links links: [], }; }
-
Обновите файл
app/[lang]/docs/layout.tsx
, чтобы использовать общие параметры:// app/[lang]/docs/layout.tsx import type { ReactNode } from "react"; import { source } from "@/lib/source"; import { DocsLayout } from "fumadocs-ui/layouts/docs"; import { baseOptions } from "@/lib/layout.shared"; export default async function Layout({ params, children, }: LayoutProps<"/[lang]/docs">) { const { lang } = await params; return ( <DocsLayout {...baseOptions(lang)} tree={source.pageTree[lang]}> {children} </DocsLayout> ); }
-
Обновите файл
app/[lang]/(home)/layout.tsx
, чтобы использовать общие параметры:// app/[lang]/(home)/layout.tsx import { HomeLayout } from "fumadocs-ui/layouts/home"; import { baseOptions } from "@/lib/layout.shared"; export default async function Layout({ children, params, }: LayoutProps<"/[lang]">) { const { lang } = await params; return <HomeLayout {...baseOptions(lang)}>{children}</HomeLayout>; }
Шаг 5. Обновите компоненты страницы
Обновите компоненты страницы (например, app/[lang]/docs/[[...slug]]/page.tsx
), чтобы они обрабатывали параметр языка:
import { source } from "@/lib/source";
import {
DocsBody,
DocsDescription,
DocsPage,
DocsTitle,
} from "fumadocs-ui/page";
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { createRelativeLink } from "fumadocs-ui/mdx";
import { getMDXComponents } from "@/mdx-components";
export default async function Page(
props: PageProps<"/[lang]/docs/[[...slug]]">,
) {
const params = await props.params;
const page = source.getPage(params.slug, params.lang);
if (!page) notFound();
const MDXContent = page.data.body;
return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDXContent
components={getMDXComponents({
// это позволяет ссылаться на другие страницы с относительными путями файлов
a: createRelativeLink(source, page),
})}
/>
</DocsBody>
</DocsPage>
);
}
export async function generateStaticParams() {
return source.generateParams();
}
export async function generateMetadata(
props: PageProps<"/[lang]/docs/[[...slug]]">,
): Promise<Metadata> {
const params = await props.params;
const page = source.getPage(params.slug, params.lang);
if (!page) notFound();
return {
title: page.data.title,
description: page.data.description,
};
}
Шаг 6. Организуйте контент для перевода
-
Создайте языковые директории для контента:
mkdir -p content/docs/en
-
Переместите существующие MDX-файлы в директорию для английского языка:
content/docs/index.mdx
→content/docs/en/index.mdx
content/docs/test.mdx
→content/docs/en/test.mdx
Шаг 7. Настройте CLI
В корне проекта создайте файл i18n.json
:
{
"$schema": "https://lingo.dev/schema/i18n.json",
"version": 1.8,
"locale": {
"source": "en",
"targets": ["es"]
},
"buckets": {
"mdx": {
"include": ["content/docs/[locale]/*.mdx"]
}
}
}
Этот файл определяет:
- файлы, которые CLI Lingo.dev должен переводить
- языки для перевода
В данном случае конфигурация переводит MDX-файлы с английского на испанский.
Важно отметить, что:
[locale]
— это плейсхолдер, который заменяется во время выполнения. Он гарантирует, что контент читается из одного места (например,src/content/docs/en/index.mdx
) и записывается в другое место (например,src/content/docs/es/index.mdx
).- CLI Lingo.dev не поддерживает рекурсивные шаблоны (например,
**/*.mdx
). Вам нужно будет создать дополнительные шаблоныinclude
, чтобы переводить файлы, находящиеся в вложенных директориях.
Чтобы узнать больше, см. конфигурация i18n.json.
Шаг 8. Переведите контент
-
Войдите в Lingo.dev через CLI:
npx lingo.dev@latest login
-
Запустите процесс перевода:
npx lingo.dev@latest run
CLI создаст директорию
content/docs/es/
для хранения переведенного контента и файлi18n.lock
для отслеживания переведенного (чтобы избежать ненужных повторных переводов).
Шаг 9. Просмотрите переведенную документацию
-
Запустите сервер разработки:
npm run dev
-
Перейдите по следующим URL-адресам:
- http://localhost:3000/en/docs для контента на английском языке
- http://localhost:3000/es/docs для контента на испанском языке