# General Translation Knowledge Base: ¿Cómo traduzco Markdown y MDX sin romper la sintaxis?
URL: https://generaltranslation.com/es/kb/translate-markdown-files.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Traduce la prosa, el texto alt de las imágenes, los títulos y las descripciones del frontmatter, y las props de componentes que muestran texto. No modifiques los bloques de código, el código inline, las importaciones, los nombres de componentes JSX, las claves del frontmatter ni las URL de los enlaces, salvo que un mapeo de configuraciones regionales las reescriba. Pon entre comillas los valores YAML traducidos y, después, ejecuta la compilación de tu sitio.
Category: Traducción
Last updated: 2026-10-20
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-20

Un archivo Markdown combina prosa con sintaxis técnica. MDX añade JavaScript mediante líneas `import`, componentes JSX y `{expressions}` que un compilador debe poder seguir analizando después de la traducción. Antes de traducir, decide qué campos contienen texto visible: puede que el `title` de un componente deba traducirse, mientras que su `id` debe permanecer estable.

## Qué se rompe cuando Markdown pasa por un traductor genérico

Un traductor que trata el archivo como texto sin formato interpreta todo su contenido como lenguaje. Estos son los fallos que conviene revisar:

* **Bloques de código y código inline.** Los comandos y los identificadores pueden acabar traducidos, de modo que `npm install` puede devolverse como `npm installer`.
* **URL y anclas de enlaces.** Un slug o un `#fragment` de un enlace puede traducirse y quedar apuntando a ninguna parte. Los encabezados traducidos también reciben nuevos ID generados, lo que rompe todos los enlaces `#anchor` que apuntan a ellos; por este motivo, Docusaurus recomienda usar [ID de encabezado explícitos](https://docusaurus.io/docs/i18n/tutorial#translate-markdown-files).
* **Frontmatter.** Claves como `title` pueden traducirse, los valores de `slug` pueden cambiar o un valor traducido puede romper el YAML. En francés se pone un espacio antes de los dos puntos, así que `title: Installer la CLI : guide rapide` es YAML no válido (el analizador `yaml` informa de un mapeo anidado). El valor debe ir entre comillas.
* **Atributos HTML.** Traduce el texto de `alt` y `title`. Conserva `class` y otros identificadores; cambia `src` o `href` solo mediante un mapeo explícito de recursos o URL localizados.
* **Importaciones MDX y JSX.** Si `import Tabs from '@theme/Tabs'` se traduce como si fuera una frase, o `<Tabs>` se convierte en `<Onglets>`, la compilación falla. La [guía de Crowdin de Docusaurus](https://docusaurus.io/docs/i18n/crowdin#mdx) advierte de que las herramientas que interpretan JSX como HTML pueden generar JSX no válido, y de que las props con valores de objeto o array son las más propensas a fallar.
* **Avisos.** Docusaurus reconoce `:::note`, `:::tip`, `:::info`, `:::warning` y `:::danger` como [palabras clave](https://docusaurus.io/docs/markdown-features/admonitions). Un `:::astuce` traducido no lo es, así que el aviso se renderiza como texto sin formato.
* **Tablas.** Una tabla GFM solo se reconoce cuando la fila de cabecera tiene el mismo número de celdas que la fila delimitadora, y una barra vertical literal dentro de una celda debe escaparse como `\|` ([especificación de GFM](https://github.github.com/gfm/#tables-extension-)). Si un traductor añade una barra vertical o un salto de línea dentro de una celda, la fila se rompe.

Aquí tienes un archivo de origen y un ejemplo ilustrativo de salida que presenta todos esos fallos. Reúne los problemas en un solo lugar y no corresponde a la salida de ninguna herramienta concreta.

```mdx
---
title: Install the CLI
slug: /install
---

import Tabs from '@theme/Tabs';

## Install the CLI {/* #install */}

Run `npm install my-cli`, then read the [setup guide](/docs/setup#api-keys).

:::tip
Use <Tabs groupId="pm">a package manager</Tabs> you already have.
:::
```

```mdx
---
titre: Installer la CLI : guide rapide
slug: /installer
---

importer Tabs depuis '@theme/Tabs';

## Installer la CLI {/* #installer */}

Exécutez `npm installer my-cli`, puis lisez le [guide](/docs/configuration#cles-api).

:::astuce
Utilisez <Onglets groupId="gp">un gestionnaire de paquets</Onglets> que vous avez déjà.
:::
```

El segundo archivo tiene una clave del frontmatter traducida, YAML no válido, un slug modificado, un import que MDX no puede analizar, un nuevo ID de encabezado, un comando roto, un enlace roto, un aviso desconocido y un componente que no existe.

## Formas de traducir Markdown y MDX

### a) Traducción de documentos con Google o DeepL

La traducción de documentos de [Google Cloud Translation](https://docs.cloud.google.com/translate/docs/supported-formats) (edición Advanced) acepta archivos de Word, PDF, PowerPoint y Excel, pero no Markdown; su traducción de texto admite texto sin formato o HTML. La [API de DeepL](https://developers.deepl.com/docs/api-reference/document) indica que la traducción de documentos Markdown (`.md`) está en beta y no menciona MDX. En cualquier caso, prueba el resultado con tus propios archivos antes de confiarle bloques de código y frontmatter.

### b) Usa un AST para separar la prosa de la sintaxis

[remark](https://github.com/remarkjs/remark) analiza Markdown y lo convierte en un árbol [mdast](https://github.com/syntax-tree/mdast). El siguiente ejemplo de extracción recorre los nodos `text` y omite el código, los atributos y el frontmatter. Es un buen punto de partida para inspeccionar el contenido, pero no un flujo de traducción completo:

```js
// extract.mjs: npm i unified remark-parse remark-stringify remark-mdx
//   remark-frontmatter remark-gfm remark-directive unist-util-visit
import { readFileSync } from 'node:fs';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkFrontmatter from 'remark-frontmatter';
import remarkGfm from 'remark-gfm';
import remarkMdx from 'remark-mdx';
import remarkDirective from 'remark-directive';
import remarkStringify from 'remark-stringify';
import { visit } from 'unist-util-visit';

const processor = unified()
  .use(remarkParse)
  .use(remarkFrontmatter, ['yaml']) // el frontmatter se convierte en un único nodo `yaml`
  .use(remarkGfm)                   // tablas
  .use(remarkMdx)                   // import/export y JSX
  .use(remarkDirective)             // avisos :::tip
  .use(remarkStringify);

const tree = processor.parse(readFileSync(process.argv[2], 'utf8'));

// Esta demostración solo extrae nodos de texto. El texto visible en los atributos
// y el frontmatter requiere un tratamiento aparte en un traductor de producción.
const segments = [];
visit(tree, 'text', (node) => {
  if (node.value.trim()) segments.push(node);
});

console.log(segments.map((n) => JSON.stringify(n.value)).join('\n'));

// Marcador de posición para una llamada de traducción: reemplaza cada segmento en el propio árbol.
for (const node of segments) node.value = node.value.toUpperCase();
console.log('\n' + processor.stringify(tree));
```

Al ejecutarlo sobre el archivo de origen anterior, con un bloque `bash` delimitado y una tabla de dos columnas añadidos, `node extract.mjs guide.mdx` imprimió estos segmentos (extracto):

```text
"Install the CLI "
"Run "
", then read the "
"setup guide"
"."
"Use "
"a package manager"
" you already have."
```

El archivo reserializado conservó el contenido del frontmatter, la importación, el ID del encabezado, el código inline, el destino del enlace, el nombre del aviso, los atributos JSX y el contenido del bloque de código, a la vez que convertía a mayúsculas los nodos de texto. Lo que no conservó fue cada byte del formato. Aparecieron tres limitaciones:

* **Las oraciones llegan fragmentadas.** &quot;Run … then read the … setup guide&quot; son cinco segmentos, por lo que un traductor no puede reordenar las palabras alrededor del código y del enlace. Los scripts de producción traducen el párrafo completo con marcadores de posición para los nodos inline.
* **Parte del texto no está en nodos `text`.** El texto `alt` de las imágenes, los valores de atributos JSX como una prop `title` y los valores del frontmatter como `title` requieren un tratamiento aparte.
* **La salida se reformatea.** `remark-stringify` volvió a ajustar el relleno de las columnas de la tabla, así que el diff muestra líneas que no modificaste.

El análisis también permite detectar antes los errores de sintaxis. Un sufijo de encabezado `{#install}` al estilo de Mintlify hizo que `remark-mdx` fallara con &quot;Could not parse expression with acorn&quot;, porque en MDX las llaves inician una expresión de JavaScript. Docusaurus también acepta la forma de comentario `{/* #install */}`, que `docusaurus write-heading-ids --syntax mdx-comment` puede escribir por ti.

El reemplazo por mayúsculas muestra qué texto selecciona el analizador; no mide la calidad de la traducción. Antes de usar un flujo de traducción, compara los campos protegidos con el origen, valida la sintaxis de YAML y MDX, y ejecuta la compilación real de tu sitio para detectar importaciones, enlaces o componentes específicos del framework que estén rotos.

### c) Un sistema de gestión de traducciones

Un sistema de gestión de traducciones (TMS) analiza el archivo por ti. Crowdin admite [Markdown](https://store.crowdin.com/md) y [MDX](https://store.crowdin.com/mdx) de forma nativa, y su [configuración del analizador](https://support.crowdin.com/parsers-configuration/) permite excluir bloques de código y determinados elementos del frontmatter; de forma predeterminada, los archivos MDX se suben como MDX v1, y para usar la v2 hay que seleccionar el tipo `mdx_v2`. Aun así, sigues teniendo que asignar las rutas de origen y de salida, sincronizar los archivos en CI y buscar soluciones para el JSX que el analizador interpreta mal.

### d) Dar instrucciones a un LLM con reglas

Un modelo que recibe el archivo completo puede conservar el contexto de cada párrafo. Indica qué campos de texto visible deben traducirse, como la prosa, el texto alt de las imágenes, los campos `title` y `description` del frontmatter y determinadas props de componentes. Protege el código, las claves estructurales, las importaciones, los nombres de componentes JSX y las palabras clave `:::`; permite cambios en las URL solo a través de tu mapeo de configuraciones regionales y exige un entrecomillado YAML válido. Nada garantiza que el modelo cumpla las reglas de un prompt, así que analiza el resultado, compila el MDX y compara el contenido protegido con el origen.

### Comparación

| Enfoque                                    | Entiende la estructura de Markdown   | MDX y JSX                                  | Frontmatter                                 | Mantiene las traducciones sincronizadas                            | Tu esfuerzo                                                                              |
| ------------------------------------------ | ------------------------------------ | ------------------------------------------ | ------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
| Traducción de documentos de Google o DeepL | DeepL `.md` en beta; Google no       | No se indica                               | Sin probar; verifícalo                      | Volver a ejecutar archivo por archivo                              | Bajo, más la revisión                                                                    |
| Script de remark                           | Sí, tú decides qué nodos             | Sí, con `remark-mdx`                       | Lo gestionas tú                             | Tú escribes la detección de cambios                                | Alto                                                                                     |
| TMS (Crowdin)                              | Sí                                   | Nativo, con salvedades de JSX documentadas | Excluye las claves que elijas               | Sincronización por CLI en CI                                       | Medio                                                                                    |
| LLM con reglas                             | Solo mediante instrucciones          | Solo mediante instrucciones                | Solo mediante instrucciones                 | Tú lo automatizas con scripts                                      | Medio, más la revisión                                                                   |
| CLI de General Translation                 | Procesamiento específico de Markdown | Procesamiento específico de MDX            | Traduce títulos y descripciones de Mintlify | Reutiliza las traducciones coincidentes en ejecuciones posteriores | Configurar las rutas de origen, revisar el resultado y ejecutar la compilación del sitio |

Usa la compatibilidad con Markdown (en beta) de DeepL para un archivo `.md` puntual que vayas a revisar a mano. Escribe un script de remark cuando necesites control total sobre un conjunto de archivos pequeño y estable. Usa un TMS si los traductores trabajan en su editor. Usa un prompt de LLM para borradores rápidos que vayas a revisar con un diff. Elige General Translation para documentación que cambia con cada lanzamiento: se encarga de generar y reutilizar las traducciones, y los archivos traducidos se quedan en tu repositorio.

## Cómo traducir Markdown y MDX con General Translation

Cuando los archivos Markdown y MDX se encuentran en un repositorio que cambia con frecuencia, la CLI de General Translation, `gt`, puede traducirlos en cada ejecución. Traduce [archivos MDX y Markdown](/docs/cli/reference/formats/mdx-md-files) y conserva su sintaxis y formato. Después de ejecutar [`npx gt init`](/docs/cli/reference/commands/init) siguiendo el [Inicio rápido de la CLI](/docs/cli/quickstart), agrega una entrada `mdx` o `md` en `files` dentro de `gt.config.json`:

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["fr", "ja"],
  "files": {
    "mdx": { "include": ["docs/[locale]/**/*.mdx"] },
    "md": { "include": ["docs/[locale]/**/*.md"] }
  }
}
```

Después, ejecuta [`npx gt translate`](/docs/cli/reference/commands/translate). La CLI lee los archivos de origen de `docs/en/` y escribe las traducciones en `docs/fr/` y `docs/ja/`. Hay algunos comportamientos que conviene tener en cuenta en la documentación:

* **ID de encabezados.** Los sufijos `{#id}` al estilo de Mintlify se mantienen asociados a sus encabezados (`gt` 2.17.3 o posterior).
* **Frontmatter.** En los sitios de Mintlify, se traducen los títulos y las descripciones del frontmatter.
* **Ejecuciones incrementales.** Las traducciones coincidentes de ejecuciones anteriores se reutilizan, y solo el contenido nuevo o modificado se traduce y se cobra. `--force` vuelve a traducirlo todo y sobrescribe los cambios locales.
* **Ediciones manuales.** La sincronización de las ediciones es de activación voluntaria, mediante [`npx gt translate --save-local`](/docs/cli/reference/commands/translate) o [`npx gt save-local`](/docs/cli/reference/commands/save-local).
* **Enlaces e importaciones.** La reescritura de URL, importaciones y rutas de recursos por configuración regional es experimental y se habilita con opciones como `--experimental-localize-static-urls`.

Ejecútalo [en CI](/docs/cli/guides/generating-translations) antes de la compilación, mantén los términos del producto en un [glosario](/docs/platform/dashboard/guides/defining-context-for-translations) compartido con la aplicación y revisa la redacción en el [editor del panel de control](/docs/platform/dashboard/guides/reviewing-translations). Antes de publicar, ejecuta la compilación y las comprobaciones de enlaces en todas las configuraciones regionales. (Consulta [General Translation vs. Google Translate](/kb/general-translation-vs-google-translate) y [General Translation vs. Crowdin](/kb/general-translation-vs-crowdin) para una comparación más amplia de ventajas y desventajas).

## Puntos clave

* Traduce oraciones completas y determinados campos de texto visible, como el texto alt, los valores del frontmatter y las props pertinentes. Conserva la sintaxis técnica y los identificadores; reescribe las URL únicamente mediante un mapeo configurado.
* La puntuación francesa `" : "` puede romper un frontmatter YAML sin comillas, y los sufijos de encabezado `{#id}` provocan errores en un analizador MDX estándar.
* La traducción de documentos de Google no admite Markdown; DeepL incluye `.md` en beta y no menciona MDX.
* La demostración con remark expone los nodos de texto, pero un flujo completo debe conservar el contexto de cada oración y gestionar el texto visible que queda fuera de esos nodos.
* La CLI de General Translation traduce archivos `md` y `mdx` sin alterar la sintaxis y reutiliza las traducciones coincidentes en ejecuciones posteriores.

## Related questions

- [¿Cómo traduzco archivos JSON de i18n?](https://generaltranslation.com/es/kb/translate-json-files.mdx): Traduce solo los valores de cadena de un archivo JSON de configuración regional. No modifiques las claves no plurales, los marcadores de posición como {{name}} ni las etiquetas, pero ten en cuenta que las claves plurales varían según el idioma: el polaco necesita inbox_few e inbox_many. Usa una herramienta o API que reconozca el formato y, después, analiza y valida el resultado antes de revisarlo.
- [¿Cómo hago que un sitio web sea multilingüe?](https://generaltranslation.com/es/kb/make-website-multilingual.mdx): Elige dónde se alojarán las traducciones (en un proxy, un plugin de CMS, un creador de sitios web o tu propio código) y después asigna a cada idioma su propia URL, tal como recomienda Google. Traduce las páginas completas, además de los títulos y las metadescripciones, vincula las versiones con hreflang y ofrece un selector de idioma en lugar de redirigir automáticamente a los visitantes.
- [Alternativas a Google Translate: General Translation vs. Google Translate](https://generaltranslation.com/es/kb/general-translation-vs-google-translate.mdx): Google Translate es una forma rápida de traducir textos puntuales, pero lanzar un producto en otro idioma también exige traducir cada cadena en su contexto, mantener una terminología coherente, gestionar correctamente las variables y los plurales, revisar las traducciones y contar con un proceso de lanzamiento. General Translation entiende el contexto de cada cadena en tu código y automatiza todo el flujo de trabajo de localización, desde el código hasta la revisión y cada lanzamiento.
- [Alternativas a Crowdin: General Translation vs. Crowdin](https://generaltranslation.com/es/kb/general-translation-vs-crowdin.mdx): Elige General Translation para mantener los textos en tus componentes y generar las traducciones con tu compilación. Crowdin gestiona proyectos de traducción en torno a archivos de recursos, traductores y flujos de trabajo de revisión, que los ingenieros conectan a la aplicación y mantienen a medida que el producto evoluciona. Crowdin sigue siendo una buena opción para la traducción comunitaria de proyectos de código abierto y los programas gestionados por proveedores.

## Previous and next questions

- Previous question: [¿Cómo traduzco archivos JSON de i18n?](https://generaltranslation.com/es/kb/translate-json-files.mdx)
- Next question: [¿Cómo traduzco subtítulos SRT sin alterar la sincronización?](https://generaltranslation.com/es/kb/translate-srt-subtitles.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/es/kb/sitemap.md) for every article.
