Fumadocs

Traducción con IA para Fumadocs con Lingo.dev CLI

¿Qué es Fumadocs?

Fumadocs es un framework de documentación de código abierto. Proporciona un sitio de documentación rápido, con seguridad de tipos, búsqueda integrada, soporte para internacionalización y una interfaz de usuario atractiva.

¿Qué es Lingo.dev CLI?

Lingo.dev es una plataforma de traducción impulsada por IA. El CLI de Lingo.dev lee archivos fuente, envía contenido traducible a modelos de lenguaje de gran escala y escribe los archivos traducidos de vuelta a tu proyecto.

Acerca de esta guía

Esta guía explica cómo configurar Lingo.dev CLI en un sitio de documentación de Fumadocs. Aprenderás cómo estructurar un proyecto con Fumadocs, configurar un pipeline de traducción y ver los resultados.

Paso 1. Configurar un proyecto de Fumadocs

  1. Crea una nueva aplicación de Fumadocs:

    npm create fumadocs-app
    
  2. Sigue las indicaciones para configurar el proyecto con los ajustes preferidos.

  3. Navega al directorio del proyecto:

    cd <project-name>
    

Paso 2. Configurar el soporte de internacionalización

Fumadocs necesita saber qué idiomas soportará tu documentación. Crearás archivos de configuración que indiquen a Fumadocs cómo manejar múltiples idiomas.

  1. Crea un archivo lib/i18n.ts para definir los idiomas soportados:

    import { defineI18n } from 'fumadocs-core/i18n';
    
    export const i18n = defineI18n({
      defaultLanguage: 'en',
      languages: ['en', 'es'],
      parser: "dir",
    });
    
  2. Actualiza el archivo lib/source.ts para usar la configuración de i18n:

    import { docs } from "@/.source";
    import { loader } from "fumadocs-core/source";
    import { i18n } from "@/lib/i18n";
    
    // Ver https://fumadocs.vercel.app/docs/headless/source-api para más información
    export const source = loader({
      // asigna una URL a tus páginas
      baseUrl: "/docs",
      source: docs.toFumadocsSource(),
      i18n,
    });
    
  3. Crea un middleware para detectar y redirigir a los usuarios según su preferencia de idioma:

    // middleware.ts
    import { createI18nMiddleware } from 'fumadocs-core/i18n/middleware';
    import { i18n } from '@/lib/i18n';
    
    export default createI18nMiddleware(i18n);
    
    export const config = {
      // Matcher que ignora `/_next/` y `/api/`
      // Es posible que necesites ajustarlo para ignorar activos estáticos en la carpeta `/public`
      matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
    };
    

Paso 3. Actualizar la estructura de la aplicación para múltiples idiomas

  1. Crea un directorio de parámetros de idioma en la carpeta app/:

    mkdir app/[lang]
    
  2. Mueve tus páginas existentes al directorio de parámetros de idioma:

    • app/docs/app/[lang]/docs/
    • app/(home)/app/[lang]/(home)/
  3. Crea un archivo app/[lang]/layout.tsx para envolver todas tus páginas específicas de idioma:

    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>
      );
    }
    

Paso 4. Crear opciones de diseño compartidas

  1. Crea un archivo lib/layout.shared.tsx para configuraciones de diseño compartidas:

    // lib/layout.shared.tsx
    import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
    import { i18n } from "@/lib/i18n";
    
    /**
     * Configuraciones de diseño compartidas
     *
     * puedes personalizar los diseños individualmente desde:
     * Diseño de inicio: app/(home)/layout.tsx
     * Diseño de documentación: 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
            </>
          ),
        },
        // ver https://fumadocs.dev/docs/ui/navigation/links
        links: [],
      };
    }
    
  2. Actualiza el archivo app/[lang]/docs/layout.tsx para usar las opciones compartidas:

    // 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>
      );
    }
    
  3. Actualiza el archivo app/[lang]/(home)/layout.tsx para usar las opciones compartidas:

    // 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>;
    }
    

Paso 5. Actualizar los componentes de página

Actualiza los componentes de página (por ejemplo, app/[lang]/docs/[[...slug]]/page.tsx) para manejar el parámetro de idioma:

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({
            // this allows you to link to other pages with relative file paths
            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,
  };
}

Paso 6. Organizar el contenido para traducción

  1. Crea directorios específicos para cada idioma para el contenido:

    mkdir -p content/docs/en
    
  2. Mueve los archivos MDX existentes al directorio de inglés:

    • content/docs/index.mdxcontent/docs/en/index.mdx
    • content/docs/test.mdxcontent/docs/en/test.mdx

Paso 7. Configurar la CLI

En la raíz del proyecto, crea un archivo i18n.json:

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": 1.8,
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {
    "mdx": {
      "include": ["content/docs/[locale]/*.mdx"]
    }
  }
}

Este archivo define:

  • los archivos que la CLI de Lingo.dev debe traducir
  • los idiomas entre los que traducir

En este caso, la configuración traduce archivos MDX del inglés al español.

Es importante tener en cuenta que:

  • [locale] es un marcador de posición que se reemplaza en tiempo de ejecución. Asegura que el contenido se lea desde una ubicación (por ejemplo, src/content/docs/en/index.mdx) y se escriba en una ubicación diferente (por ejemplo, src/content/docs/es/index.mdx).
  • La CLI de Lingo.dev no admite patrones glob recursivos (por ejemplo, **/*.mdx). Necesitarás crear patrones include adicionales para traducir archivos que existan dentro de directorios anidados.

Para obtener más información, consulta configuración de i18n.json.

Paso 8. Traducir el contenido

  1. Regístrate para obtener una cuenta de Lingo.dev.

  2. Inicia sesión en Lingo.dev a través de la CLI:

    npx lingo.dev@latest login
    
  3. Ejecuta el proceso de traducción:

    npx lingo.dev@latest run
    

    La CLI creará un directorio content/docs/es/ para almacenar el contenido traducido y un archivo i18n.lock para realizar un seguimiento de lo que se ha traducido (para evitar retraducciones innecesarias).

Paso 9. Visualizar la documentación traducida

  1. Inicia el servidor de desarrollo:

    npm run dev
    
  2. Navega a las siguientes URLs: