{"id":49039565,"url":"https://github.com/wsj-br/ai-i18n-tools","last_synced_at":"2026-06-08T01:05:41.176Z","repository":{"id":350591703,"uuid":"1203264603","full_name":"wsj-br/ai-i18n-tools","owner":"wsj-br","description":"A fully automated i18n (internationalisation) toolkit for JavaScript and TypeScript projects. Leverages AI (via OpenRouter) to manage the complete translation workflow—from extracting strings to generating locale-ready JSON files, Markdown documentation, Docusaurus-powered sites, and SVG assets—supporting as many languages as required.","archived":false,"fork":false,"pushed_at":"2026-05-22T22:39:28.000Z","size":15623,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-23T00:25:12.837Z","etag":null,"topics":["ai-tools","documentation-tool","docusaurus","i18n","internationalization","javascript","markdown","multi-language-support","openrouter","translation","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wsj-br.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-06T22:08:59.000Z","updated_at":"2026-05-22T22:39:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/wsj-br/ai-i18n-tools","commit_stats":null,"previous_names":["wsj-br/ai-i18n-tools"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/wsj-br/ai-i18n-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wsj-br%2Fai-i18n-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wsj-br%2Fai-i18n-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wsj-br%2Fai-i18n-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wsj-br%2Fai-i18n-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wsj-br","download_url":"https://codeload.github.com/wsj-br/ai-i18n-tools/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wsj-br%2Fai-i18n-tools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34043826,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-tools","documentation-tool","docusaurus","i18n","internationalization","javascript","markdown","multi-language-support","openrouter","translation","typescript"],"created_at":"2026-04-19T14:12:25.937Z","updated_at":"2026-06-08T01:05:41.171Z","avatar_url":"https://github.com/wsj-br.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca id=\"ai-i18n-tools\"\u003e\u003c/a\u003e\n# ai-i18n-tools\n\n[![npm version](https://img.shields.io/npm/v/ai-i18n-tools.svg)](https://www.npmjs.com/package/ai-i18n-tools)\n[![npm downloads](https://img.shields.io/npm/dm/ai-i18n-tools.svg)](https://www.npmjs.com/package/ai-i18n-tools)\n[![Node.js](https://img.shields.io/node/v/ai-i18n-tools.svg)](https://nodejs.org/)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)\n[![CI](https://github.com/wsj-br/ai-i18n-tools/actions/workflows/ci.yml/badge.svg)](https://github.com/wsj-br/ai-i18n-tools/actions/workflows/ci.yml)\n\nA CLI and toolkit for internationalizing JavaScript/TypeScript applications and documentation sites using large language models via [OpenRouter](https://openrouter.ai/). Three modular workflows, all sharing a single config file, support different translation needs:\n\n- **Workflow 1 — UI Translation:** Extracts `t(\"…\")` calls from JS/TS (and optionally from `.astro` files) and generates flat, per-locale JSON for i18next or static SSG lookup.\n- **Workflow 2 — Document Translation:** Translates markdown, MDX, and `.astro` pages (for websites and Starlight) listed in `docs[].contentPaths` using `translate-docs`.\n- **Workflow 3 — JSON File Translation:** Translates arbitrary nested JSON bundles defined in `json[]`. Use `translate-json` when UI copy is stored in per-locale JSON files instead of using `t()` in source.\n\n**SVG** assets are translated using `features.translateSVG`, the top-level `svg` block, and `translate-svg`—not `docs[].contentPaths`.\n\n**Which workflow should I use?**\n- Source uses `t()` → **Workflow 1** (`extract` / `translate-ui`)\n- Localized pages or Docusaurus catalog JSON → **Workflow 2** (`translate-docs`)\n- Only standalone, nested JSON locale files → **Workflow 3** (`translate-json`)\n\nAll workflows maintain a file/SQLite cache to ensure that only new or changed segments (strings or text chunks) are sent to the LLM.\n\n\u003csmall\u003e**Read in other languages:** \u003c/small\u003e\n\u003csmall id=\"lang-list\"\u003e[English (GB)](./README.md) · [Deutsch](./translated-docs/README.de.md) · [Español](./translated-docs/README.es.md) · [Français](./translated-docs/README.fr.md) · [हिन्दी](./translated-docs/README.hi.md) · [日本語](./translated-docs/README.ja.md) · [한국어](./translated-docs/README.ko.md) · [Português (Brasil)](./translated-docs/README.pt-BR.md) · [中文 (中国大陆)](./translated-docs/README.zh-CN.md) · [中文 (台灣)](./translated-docs/README.zh-TW.md)\u003c/small\u003e\n\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n**Table of Contents** \n\n- [Core workflows](#core-workflows)\n- [Installation](#installation)\n  - [Using the CLI](#using-the-cli)\n- [OpenRouter](#openrouter)\n- [Quick start](#quick-start)\n  - [Workflow 1 - UI Translation](#workflow-1---ui-translation)\n  - [Workflow 2 - Document Translation](#workflow-2---document-translation)\n  - [Astro (plain Astro \u0026 Starlight)](#astro-plain-astro--starlight)\n  - [Combined workflow](#combined-workflow)\n- [Runtime helpers](#runtime-helpers)\n- [CLI commands](#cli-commands)\n- [Documentation](#documentation)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n\n\n\n\n\u003ca id=\"core-workflows\"\u003e\u003c/a\u003e\n## Core workflows\n\n**Workflow 1 - UI Translation** — for any JS/TS project using i18next (React, Next.js, Node.js, CLIs) or static Astro SSG\n\nScans source files for `t(\"…\")` / `i18n.t(\"…\")` literals (add `.astro` to `ui.uiExtractor.extensions` for Astro frontmatter and template expressions), builds a master catalog (`strings.json`), translates missing entries per locale via OpenRouter, and writes flat JSON files (`de.json`, `pt-BR.json`, …). English source text is the runtime lookup key in those bundles — `strings.json` is the extraction cache, not the runtime bundle.\n\n**Workflow 2 - Document Translation** — for markdown, MDX, and `.astro` under `docs[].contentPaths`\n\nDesigned primarily for **markdown, MDX, and `.astro` documentation** (Docusaurus, [Astro Starlight](https://starlight.astro.build/), plain README files, and plain Astro marketing pages). `translate-docs` writes localised copies with a shared SQLite cache. On Docusaurus sites, set `docs[].docusaurusCatalogDir` to the `write-translations` catalog folder so shell JSON (navbar, footer, theme strings) is translated in the same command. `docs[].docsOutput.style` supports `\"nested\"`, `\"flat\"`, `\"doc-system\"`, and aliases `\"docusaurus\"` / `\"astro-starlight\"` (see [Output layouts](docs/GETTING_STARTED.md#output-layouts) in Getting Started). Arbitrary nested UI JSON that is not a Docusaurus catalog belongs in Workflow 3 (`json[]` / `translate-json`), not `docs[]`.\n\n**Workflow 3 - JSON file translation** — nested locale JSON without `t()` in source\n\nTranslate files such as `src/i18n/en/translation.json` via top-level `json[]`, `features.translateJson`, and `translate-json`. Scaffold with `init -t ui-json-bundles`.\n\nAll workflows share `ai-i18n-tools.config.json` and can be combined; `sync` runs extract, UI translation, translate SVG, `translate-docs`, and `translate-json` in order according to your `features` flags.\n\n---\n\n\u003ca id=\"installation\"\u003e\u003c/a\u003e\n## Installation\n\nThe published package is **ESM-only** (`\"type\": \"module\"`). Node.js `\u003e=22.16.0` required.\n\n```bash\nnpm install ai-i18n-tools\n# or\npnpm add ai-i18n-tools\n```\n\n\u003ca id=\"using-the-cli\"\u003e\u003c/a\u003e\n### Using the CLI\n\n**Per-project (recommended)** — install as a dev dependency, then run via `npx`, `pnpm exec`, or a `package.json` script:\n\n```bash\npnpm add -D ai-i18n-tools     # or: npm i -D ai-i18n-tools\nnpx ai-i18n-tools sync        # or: pnpm exec ai-i18n-tools sync\n```\n\n```json\n\"scripts\": {\n  \"i18n:extract\": \"ai-i18n-tools extract\",\n  \"i18n:sync\": \"ai-i18n-tools sync\",\n  \"i18n:translate:ui\": \"ai-i18n-tools translate-ui\",\n  \"i18n:translate:svg\": \"ai-i18n-tools translate-svg\",\n  \"i18n:translate:docs\": \"ai-i18n-tools translate-docs\",\n  \"i18n:translate:json\": \"ai-i18n-tools translate-json\",\n  \"i18n:translate\": \"ai-i18n-tools translate-docs\",\n  \"i18n:dashboard\": \"ai-i18n-tools dashboard\"\n}\n```\n\nYou can also use the ai-i18n-tools CLI commands directly, for instance `ai-i18n-tools sync`.\n\n\nPrefer `sync` over hand-chaining `extract`, `translate-ui`, `translate-svg`, `translate-docs`, and `translate-json` — order and feature flags are easy to get wrong when run manually. See [Recommended `package.json` scripts](docs/GETTING_STARTED.md#recommended-packagejson-scripts) in Getting Started.\n\n**Zero-install one-off** — `npx ai-i18n-tools \u003ccmd\u003e` or `pnpm dlx ai-i18n-tools \u003ccmd\u003e` (downloads for that invocation only).\n\n\u003e **Tip:** To run `ai-i18n-tools` bare in an interactive shell without `npx`, add `node_modules/.bin` to your `PATH` (bash/zsh: `export PATH=\"$PWD/node_modules/.bin:$PATH\"`). See [Getting Started](docs/GETTING_STARTED.md#installation) for direnv and Windows instructions.\n\nSet your OpenRouter API key:\n\n```bash\nexport OPENROUTER_API_KEY=sk-or-v1-your-key-here\n```\n\n---\n\n\u003ca id=\"openrouter\"\u003e\u003c/a\u003e\n## OpenRouter\n\nCommands that call OpenRouter (`translate-ui`, `translate-docs`, `translate-json`, `sync`, `check-models`, and related scripts) need `OPENROUTER_API_KEY` in the environment. `check-markdown` does not use OpenRouter.\n\nIn `ai-i18n-tools.config.json`, the `openrouter` object includes model lists, `baseUrl`, `maxTokens`, `temperature`, and `requestTimeoutMs`: the maximum time in milliseconds to wait for each HTTP request to OpenRouter (chat completions and internal `GET /models` calls). The default is `30000` (30 seconds).\n\nRun `ai-i18n-tools check-models` to verify each configured model id against OpenRouter’s live catalog. It reports ids that are missing or past `expiration_date`, lists valid models with estimated input/output pricing (USD per 1M tokens), and exits with a non-zero status when any configured id is invalid. It requires `OPENROUTER_API_KEY`.\n\n---\n\n\u003ca id=\"quick-start\"\u003e\u003c/a\u003e\n## Quick start\n\n\u003ca id=\"workflow-1---ui-translation\"\u003e\u003c/a\u003e\n### Workflow 1 - UI Translation\n\n```bash\n# 1. Create config (default ui-markdown; plain Astro: init -t ui-astro-website)\nnpx ai-i18n-tools init\n\n# 2. Extract UI strings to strings.json\nnpx ai-i18n-tools extract\n\n# 3. Translate to all target locales\nnpx ai-i18n-tools translate-ui\n```\n\nThen wire i18next in your app using the helpers from `'ai-i18n-tools/runtime'`. See [Step 4: Wire i18next at runtime](docs/GETTING_STARTED.md#step-4-wire-i18next-at-runtime) in the Getting Started guide for the full setup.\n\n\u003ca id=\"workflow-2---document-translation\"\u003e\u003c/a\u003e\n### Workflow 2 - Document Translation\n\nThe default `init` template (`ui-markdown`) enables UI extraction only. Use a docs-oriented template (or enable `features.translateDocs` and add `docs[]`) before `translate-docs`:\n\n```bash\n# Docusaurus docs + optional write-translations catalog\nnpx ai-i18n-tools init -t ui-docusaurus\n\n# Astro Starlight documentation\n# npx ai-i18n-tools init -t ui-starlight\n\n# Plain Astro website — UI extraction for t() in .astro; add docs[] for page HTML (see Astro below)\n# npx ai-i18n-tools init -t ui-astro-website\n\nnpx ai-i18n-tools translate-docs\nnpx ai-i18n-tools status\n# npx ai-i18n-tools translate-docs --locale de   # single locale\n```\n\nEdit `ai-i18n-tools.config.json`: set `docs[].contentPaths` to markdown, MDX, and/or `.astro` sources; `docs[].outputDir` and `docs[].docsOutput.style` (`\"docusaurus\"`, `\"astro-starlight\"`, `\"flat\"`, etc.). Full field reference: [Workflow 2 - Document Translation](docs/GETTING_STARTED.md#workflow-2---document-translation).\n\n\u003ca id=\"astro-plain-astro--starlight\"\u003e\u003c/a\u003e\n### Astro (plain Astro \u0026 Starlight)\n\n**Astro Starlight** — `init -t ui-starlight`, then `translate-docs`. Starlight UI overrides can use `src/content/i18n/en.json` with `jsonPathTemplate` in a separate `docs[]` block when needed ([Getting Started → Workflow 2](docs/GETTING_STARTED.md#step-1-initialise-for-documentation)).\n\n**Plain Astro** (marketing or app sites, not Starlight) — combine [Astro built-in i18n routing](https://docs.astro.build/en/guides/internationalization/) with ai-i18n-tools. Reference project: [`examples/astro-website`](examples/astro-website/) (English at `/`, locales at `/{locale}/`).\n\nMost teams use a **hybrid** of two pipelines:\n\n| Pipeline | Use for | Commands | Output |\n|----------|---------|----------|--------|\n| **Page HTML** | Headings, paragraphs, nav labels, inline arrays in the template body | `translate-docs` | `src/pages/{locale}/index.astro` per locale |\n| **UI strings (`t()`)** | Frontmatter data, tab labels, shared arrays | `extract` → `translate-ui` | `public/locales/{locale}.json` (English source as key) |\n\nScaffold UI with `init -t ui-astro-website`. For hardcoded HTML in `.astro` pages, enable `features.translateDocs` and add a `docs[]` block with `docsOutput.style: \"astro-starlight\"` (see [Astro website pages (parse-and-replace)](docs/GETTING_STARTED.md#astro-website-pages-parse-and-replace)). Keep `targetLocales`, `i18n.locales` in `astro.config.mjs`, and `ui-languages.json` aligned (Astro routes use lowercase codes such as `pt-br`; flat bundle filenames follow config casing, e.g. `pt-BR.json`).\n\nWire `t()` at build time without i18next unless you add client islands — see [Astro website UI strings (SSG)](docs/GETTING_STARTED.md#astro-website-ui-strings-ssg) and the example’s `src/i18n/t.ts`.\n\n\u003ca id=\"combined-workflow\"\u003e\u003c/a\u003e\n### Combined workflow\n\n```bash\nnpx ai-i18n-tools sync   # extract → translate-ui → translate-svg → translate-docs → translate-json (per features)\n```\n\n---\n\n\u003ca id=\"runtime-helpers\"\u003e\u003c/a\u003e\n## Runtime helpers\n\nThe following helpers are exported from `'ai-i18n-tools/runtime'` and work in any JavaScript environment. You do not need to import i18next to use them:\n\n| Helper                                                                 | Description                                                                                                                            |\n|------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|\n| `defaultI18nInitOptions(sourceLocale)`                                 | Standard i18next init options for key-as-default setups.                                                                               |\n| `setupKeyAsDefaultT(i18n, { stringsJson, sourcePluralFlatBundle? })`   | Recommended wiring: key-trim + plural `wrapT` from `strings.json`, optionally merges `translate-ui` `{sourceLocale}.json` plural keys. |\n| `wrapT(i18n, options)`                                                 | Lower-level plural-aware `t()` wrapper (usually installed by `setupKeyAsDefaultT`).                                                    |\n| `buildPluralIndexFromStringsJson(entries)`                               | Builds the plural group index `wrapT` uses from catalog rows with `\"plural\": true`.                                                    |\n| `extractInterpolationNamesForWrap(key)`                                  | Parses `{{var}}` names from a source key for `wrapT` / key-trim fallback.                                                              |\n| `wrapI18nWithKeyTrim(i18n)`                                            | Lower-level key-trim wrapper only (deprecated for app wiring; prefer `setupKeyAsDefaultT`).                                            |\n| `makeLocaleLoadersFromManifest(uiLanguages, sourceLocale, makeLoader)` | Builds the `localeLoaders` map for `makeLoadLocale` from `ui-languages.json` (every `code` except `sourceLocale`).                     |\n| `makeLoadLocale(i18n, loaders, sourceLocale)`                          | Factory for async locale file loading.                                                                                                 |\n| `getTextDirection(lng)`                                                | Returns `'ltr'` or `'rtl'` for a BCP-47 code.                                                                                          |\n| `applyDirection(lng, element?)`                                        | Sets `dir` attribute on `document.documentElement`.                                                                                    |\n| `getUILanguageLabel(lang, t)`                                          | Display label for a language menu row (with i18n).                                                                                     |\n| `getUILanguageLabelNative(lang)`                                       | Display label without calling `t()` (header-style).                                                                                    |\n| `interpolateTemplate(str, vars)`                                       | Low-level `{{var}}` substitution on a plain string (used internally; app code should use `t()` instead).                               |\n| `flipUiArrowsForRtl(text, isRtl)`                                      | Flip `→` to `←` for RTL layouts.                                                                                                       |\n\n---\n\n\u003ca id=\"cli-commands\"\u003e\u003c/a\u003e\n## CLI commands\n\n```bash\nai-i18n-tools version\nai-i18n-tools check-models\nai-i18n-tools init [-t ui-markdown|ui-docusaurus|ui-starlight|ui-astro-website|ui-json-bundles] [-o path] [--with-translate-ignore]\nai-i18n-tools write-heading-ids …\nai-i18n-tools extract\nai-i18n-tools translate-docs …\nai-i18n-tools translate-json …\nai-i18n-tools translate-svg …\nai-i18n-tools translate-ui …\nai-i18n-tools sync-ui …\nai-i18n-tools lint-source …\nai-i18n-tools check-markdown [-p|--path \u003cpath\u003e] [-f|--file \u003cpath\u003e] [--json] [--no-cache]\nai-i18n-tools export-ui-xliff …\nai-i18n-tools sync …\nai-i18n-tools status …\nai-i18n-tools statistics …\nai-i18n-tools cleanup …\nai-i18n-tools clean-temp …\nai-i18n-tools dashboard …\nai-i18n-tools generate-ui-languages [--master path] [--dry-run]\nai-i18n-tools glossary-generate\nai-i18n-tools help [command]\n```\n\n\nComplete per-command flag lists are in [Getting Started — CLI reference](docs/GETTING_STARTED.md#cli-reference). Run `ai-i18n-tools \u003ccommand\u003e --help` for built-in usage text.\n\nGlobal options on every command: `-c \u003cconfig\u003e` (default: `ai-i18n-tools.config.json`), `-v` (verbose), optional `-w` / `--write-logs [path]` to tee console output to a log file (default: under the translation cache directory), `-V` / `--version`, and `-h` / `--help`. Several commands accept `-l` / `--locale \u003ccodes\u003e` (comma-separated BCP-47) to limit target locales; `lint-source` uses a single source locale. See [Getting Started](docs/GETTING_STARTED.md#cli-reference) for the command overview table.\n\n---\n\n\u003ca id=\"documentation\"\u003e\u003c/a\u003e\n## Documentation\n\n- [Getting Started](docs/GETTING_STARTED.md) - full setup for all workflows (UI, docs/`.astro`, JSON bundles, Astro Starlight and plain Astro), CLI reference, and config field reference.\n- [Locale assets guide](docs/LOCALE-ASSETS-GUIDE.md) - screenshots and illustrated SVGs in translated docs (Patterns A–E, flat link rewriter, screenshot scripts).\n- [Package Overview](docs/PACKAGE_OVERVIEW.md) - architecture, internals, programmatic API, and extension points.\n- [AI Agent Context](docs/ai-i18n-tools-context.md) - **for apps using the package:** integration prompts for downstream projects (copy into your repo’s agent rules).\n- Maintainer internals for **this** repository: `dev/package-context.md` (clone-only; not on npm).\n\n---\n\n\u003ca id=\"license\"\u003e\u003c/a\u003e\n## License\n\nMIT © [Waldemar Scudeller Jr.](https://github.com/wsj-br)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwsj-br%2Fai-i18n-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwsj-br%2Fai-i18n-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwsj-br%2Fai-i18n-tools/lists"}