BabelizeBabelize
Features

File Formats

Babelize writes JSON locale files for JavaScript frameworks and gettext .po/.mo catalogues for Django, one per language, with placeholders preserved, and translates Markdown and MDX docs pages.

Babelize uses JSON locale files for React, Next.js, Vue, React Native and static HTML projects, and gettext catalogues (.po/.mo) for Django. When it scans your repository, it extracts translatable strings from your source code and writes a locale file for every target language.

Locale Files: JSON

Each locale gets its own file, for example en.json, es.json, and fr.json. Every target file mirrors the keys of the source file, so your i18n library (such as next-intl, react-i18next, or vue-i18n) can load them side by side.

FormatExtensionCommon Use
JSON.jsonReact, Next.js, static HTML, Vue (beta), React Native (beta)
gettext.po, .moDjango (see below)
Markdown / MDX.md, .mdx (+ Fumadocs meta.json)Documentation pages (see Markdown & MDX Docs)

Nested keys group related strings:

{
  "messages": {
    "greeting": "Hello, {name}",
    "farewell": "Goodbye"
  }
}

Flat keys work too:

{
  "greeting": "Hello, {name}",
  "farewell": "Goodbye"
}

When translating, Babelize:

  • Preserves keys and nesting exactly; only string values are translated
  • Leaves numeric and boolean values untouched
  • Keeps placeholders such as {name} intact (see Placeholder Protection)

Locale Files: gettext (Django)

Django projects use gettext catalogues instead of JSON: <LOCALE_PATHS[0]>/<lang>/LC_MESSAGES/django.po (by default locale/ next to manage.py).

  • Strings come from Python files (.py: existing gettext calls plus hardcoded UI strings in models, forms, admin and views) and Django templates ({% trans %} / {% blocktrans %}, with hardcoded text wrapped in {% translate %})
  • Existing .po translations are kept, never re-translated; fuzzy entries are left for you to review
  • .mo files are recompiled when they are tracked in the repository
  • LANGUAGES and LOCALE_PATHS in settings.py are updated

See Django for details and current limitations.

Documentation: Markdown and MDX

Docs pages are translated as whole files, not through a locale file. install.mdx gets install.es.mdx next to it (or es/install.mdx), with only the text readers see translated and code, imports and JSX left alone. Translations are recorded per paragraph in .babelize/local/docs-lock.json. This runs in the CLI and the MCP server. See Markdown & MDX Docs.

Not Supported

Other locale formats, such as YAML, XLIFF, ARB, or iOS/Android string files, are not supported yet.

Source Files Scanned

Babelize extracts hardcoded strings from these source file types:

ExtensionFramework
.js, .jsx, .ts, .tsxReact and Next.js (including Gatsby, Remix, and Astro projects detected as React)
.vueVue single-file components and Nuxt (beta)
.htmlStatic HTML/CSS/JS sites
.py, Django templates (.html under templates/)Django

Placeholder Protection

Babelize automatically detects and protects common placeholder patterns:

PatternExampleHandling
Named and positional variables{name}, {0}, {price, number}Protected
i18next / Handlebars / Mustache{{count}}, {{- html}}, $t(key)Protected
Printf-style%s, %d, %1$s, %(name)s, %(price).2f, %%, %@Protected
Python str.format{}, {name}Protected
HTML entities&mdash;, &nbsp;, &#8217;Protected
Template literals${variable}Protected
Tags<0>text</0>, <b>, <Link href="…">Tag markers protected; the text between them is translated
URLs, emails, inline codehttps://…, help@…, `npm i`Protected
ICU MessageFormat{count, plural, one {…} other {…}}Rebuilt with the target language's plural categories (e.g. Polish one/few/many/other, Japanese other only). An LLM (your own key) translates the whole message; Babelize's translator translates the branches, together where they fit in one sentence so they're worded alike. The result must parse and keep the same arguments and select branches

Protected spans must come back exactly once. If a translation drops, repeats or invents one — or returns an invalid ICU message, mismatched tags, or the untranslated sentence — Babelize asks the model once more with a note about what was wrong. If it still fails, the string is not written to the locale file and is reported with the reason, so your app shows the source text instead of a broken translation, and the next run retries it.

Never-translate glossary terms are protected the same way, and "always translate as" terms are sent to the model as required terminology.

Encoding

All files must be UTF-8 encoded. Other encodings are converted automatically with a warning.

Further Reading

Last updated: 2026-11-01

How is this guide?

On this page