La interfaz de administración de EmDash es traducible usando Lingui para la extracción de mensajes y Lunaria para el seguimiento del progreso de las traducciones. Todas las traducciones se almacenan en archivos PO (gettext) — uno por locale.
Estado de las traducciones
Consulta el panel de traducciones para ver el progreso actual de todos los locales.
Quién puede traducir
Las traducciones deben provenir de hablantes nativos o fluidos. No aceptamos traducciones generadas por máquina. Si usas herramientas de IA para asistirte, debes revisar cada cadena manualmente y probar el resultado en contexto (consulta Probar tus traducciones más abajo).
Preferimos que una cadena quede sin traducir a que tenga una mala traducción. Una traducción incorrecta es peor que mostrar el texto en inglés por defecto — induce activamente a error a los usuarios.
Estructura de archivos
Los catálogos de traducción se encuentran en packages/admin/src/locales/:
packages/admin/src/locales/
├── en/
│ └── messages.po # English (source)
├── de/
│ └── messages.po # German
└── ...
Cada archivo .po contiene pares msgid/msgstr. El msgid es el texto fuente en inglés; el msgstr es tu traducción. Un msgstr vacío significa “aún no traducido” — Lingui usará el inglés como respaldo en tiempo de ejecución.
Traducir cadenas
-
Consulta el panel de traducciones para ver qué necesita trabajo. Revisa las PR abiertas para evitar duplicar esfuerzos.
-
Haz fork del repositorio y crea una rama:
git checkout -b i18n/de -
Abre el archivo PO de tu locale (por ej.,
packages/admin/src/locales/de/messages.po). -
Completa las traducciones. Cada entrada tiene este aspecto:
#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr ""Completa el
msgstr:#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr "Mit Passkey anmelden" -
Prueba tus traducciones (ver más abajo).
-
Abre una PR apuntando a
main. Formato del título:i18n(de): add/update German translations.
Qué traducir
- El valor
msgstrde cada entrada.
Qué NO traducir
- Los valores
msgid— son claves de búsqueda. - Los marcadores de interpolación como
{error},{email},{label}— mantenlos exactamente como están. - Las etiquetas de estilo XML como
<0>,</0>— envuelven elementos interactivos (enlaces, botones). Conserva las etiquetas y traduce el texto entre ellas. - Los comentarios que comienzan con
#:— son referencias al código fuente añadidas por Lingui.
Interpolación y etiquetas
Algunas cadenas contienen marcadores y etiquetas:
msgid "Authentication error: {error}"
msgstr "Authentifizierungsfehler: {error}"
msgid "Don't have an account? <0>Sign up</0>"
msgstr "Noch kein Konto? <0>Registrieren</0>"
msgid "If an account exists for <0>{email}</0>, we've sent a sign-in link."
msgstr "Falls ein Konto für <0>{email}</0> existiert, haben wir einen Anmeldelink gesendet."
Los marcadores ({error}, {email}) se reemplazan por valores dinámicos en tiempo de ejecución. Las etiquetas (<0>...</0>) envuelven componentes React. Ambos deben aparecer en tu traducción exactamente como en el texto fuente — mismos nombres, misma anidación.
Probar tus traducciones
-
Compila y ejecuta la demo:
pnpm run locale:compile pnpm build pnpm --filter emdash-demo dev -
Cambia el locale en la página de Configuración de la administración y verifica que tus traducciones se ven correctas en contexto.
Locale pseudo
EmDash incluye un locale pseudo que transforma todas las cadenas envueltas en caracteres acentuados similares — "Dashboard" se convierte en "Ðàšĥƀöàřð", y así sucesivamente. Cualquier cadena que aparezca en inglés normal mientras el locale pseudo está activo carece de un envoltorio t..“ o proviene de fuera del catálogo.
Para activarlo, añade lo siguiente a tu archivo .env en el directorio de la demo:
EMDASH_PSEUDO_LOCALE=1
Luego reinicia el servidor de desarrollo. El locale pseudo aparece como Pseudo en el selector de idioma de la página de inicio de sesión y en Configuración. Cámbialo para detectar cadenas sin envolver de un vistazo.
Añadir un nuevo idioma
Si tu idioma aún no tiene un archivo PO:
-
Añade el locale a
packages/admin/src/locales/locales.ts:export const LOCALES: LocaleDefinition[] = [ { code: "en", label: "English", enabled: true }, { code: "de", label: "Deutsch", enabled: true }, // ... { code: "ja", label: "日本語", enabled: false }, // add yours ];Esta es la única fuente de verdad —
lingui.config.ts,lunaria.config.tsy el runtime de la administración derivan sus listas de locales de este archivo. Estableceenabled: falsea menos que tus traducciones tengan una cobertura del 100 % — lo habilitaremos cuando la traducción alcance una cobertura suficiente. -
Ejecuta la extracción para generar el archivo PO vacío:
pnpm run locale:extractEsto crea
packages/admin/src/locales/{your-locale}/messages.pocon todas las cadenas listas para traducir. -
Traduce y prueba siguiendo los pasos anteriores.
Estándares de traducción
Exactitud
Las traducciones deben reflejar fielmente el texto fuente en inglés a nivel de hablante nativo. No añadas, elimines ni reinterpretes el significado. Si una cadena fuente es ambigua, consulta el comentario #: para la ubicación del archivo fuente — lee el código del componente para entender el contexto.
Consistencia
Usa terminología consistente dentro de tu locale. Si traduces “collection” como “Sammlung” en un lugar, no cambies a “Kollektion” en otro. Si tu idioma ya tiene traducciones, lee el archivo PO existente antes de empezar para ajustarte a la terminología establecida.
Tono
La interfaz de administración usa un tono directo y profesional. Mantén ese mismo tono en tu idioma — evita formulaciones excesivamente formales o excesivamente informales.
Traducciones asistidas por IA
Puedes usar herramientas de IA para redactar borradores de traducciones, pero:
- Debes revisar cada cadena tú mismo. Las herramientas de IA cometen errores sutiles que solo un hablante fluido detectaría — registro incorrecto, frases poco naturales, términos técnicos equivocados.
- Debes probar el resultado en la interfaz de administración en ejecución. Las herramientas de IA no son conscientes de las restricciones de diseño ni del contexto de la interfaz.
- Indica el uso de IA en la descripción de tu PR.
- Las PR con traducciones automáticas evidentemente no revisadas serán cerradas.
Traducciones parciales
Las traducciones parciales son bienvenidas. No necesitas traducir todas las cadenas en una sola PR — cualquier progreso ayuda. Las cadenas no traducidas usarán el inglés como respaldo en tiempo de ejecución.