# 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 el texto dirigido a los lectores sin alterar el código ejecutable, las importaciones, los nombres de componentes JSX ni los identificadores de máquina. General Translation procesa Markdown y MDX directamente, incluidas las props que muestran texto y los títulos del frontmatter, y reutiliza las traducciones coincidentes a medida que cambia la documentación. Revisa los archivos localizados y ejecuta la compilación del sitio antes de publicar.
Category: Traducción
Last updated: 2026-10-30
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.

## Video

The video is narrated in English, with English captions.

[How do I translate Markdown and MDX without breaking syntax?](https://caxecubb9c64cezv.public.blob.vercel-storage.com/films/kb-translate-markdown-files.mp4) (48 s)

Translate prose, image alt text, frontmatter titles and descriptions, and display-text component props. Keep code blocks, inline code, imports, JSX component names, frontmatter keys, and link URLs unchanged, quote translated YAML values, then run your site's build. With General Translation, add an mdx or md entry under files in `gt.config.json` and run `npx gt translate`.

## 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).

### ¿Qué partes de un componente MDX deben traducirse?

General Translation distingue entre el texto que ve el lector y los identificadores que usa
el sitio. En este ejemplo de origen, el título del aviso necesita traducirse tanto
como su contenido:

```mdx title="docs/en/deployment.mdx"
---
title: Deployment guide
slug: deployment-guide
---

import { Callout } from '@/components/Callout';

<Callout id="backup" type="warning" title="Back up your database first">
  Keep a backup before deploying.
</Callout>
```

| Parte del origen                               | Tratamiento                                                               |
| ---------------------------------------------- | ------------------------------------------------------------------------- |
| `title` del frontmatter                        | Traducir el título de la página                                           |
| `title` y cuerpo del aviso                     | Traducir el texto visible                                                 |
| `slug` del frontmatter e `id` del aviso        | Conservar los identificadores que usan las rutas y los enlaces            |
| `Callout`, nombres de props y `type="warning"` | Conservar el contrato del componente                                      |
| Ruta de importación                            | Conservarla, salvo que una regla de localización configurada la reescriba |

La misma distinción se aplica dentro de los bloques de código: los comentarios explicativos se pueden
traducir, mientras que los comandos y los identificadores se mantienen intactos. Al comparar un
archivo traducido con su origen, admite que la redacción de los comentarios dentro de los bloques de código
difiera, en lugar de exigir que cada bloque sea idéntico byte a byte. Compila el resultado
con el proceso de compilación de tu sitio de documentación, donde se definen el componente importado y sus props,
y comprueba el aviso renderizado y su ancla en cada configuración regional. Una comprobación independiente de la sintaxis MDX
no resuelve los componentes ni el enrutamiento del sitio.

## 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 traduzco archivos de configuración regional YAML?](https://generaltranslation.com/es/kb/translate-yaml-files.mdx): Traduce solo los valores de cadena y deja intactas las claves, los marcadores de posición como %{name} o {{name}} y las anclas. Pon entre comillas los valores que contengan dos puntos o empiecen por % o {, define la raíz de configuración regional o el nombre de cada archivo y añade las claves de plural que necesite el idioma de destino. La CLI de General Translation traduce los valores YAML en el mismo documento y no modifica las claves.
- [¿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.
