Your locale files stop falling behind

AI Translate i18n BYOK is a GitHub Action: on every push or pull request it finds the i18n keys that are new or changed in your source language and translates only those — nested JSON like locales/en.json → it.json, de.json…, and Markdown docs/*.md → docs/<lang>/. Placeholders ({name}, %s, ICU plurals, HTML tags) are preserved and verified. It runs in your own Actions runner with your own OpenAI-compatible key: no server of ours, no per-word plan, no seat pricing. Pro is $49 per year per organization, no auto-renewal.

Get the Pro key — $49/year Install free

The problem

Every pull request adds or rewords a few strings in en.json. Nobody updates it.json and de.json in the same PR, so the other languages silently drift: missing keys fall back to English, changed keys keep the old meaning, and a release later someone batch-exports everything to a translation platform priced per seat or per hosted word.

This action closes the gap where it opens: in the same push. It diffs the source file against a lock file (.ai-translate-lock.json, a hash per key), sends only the new or changed strings to your AI provider, writes the translations back into each target file keeping your key order and nesting, and leaves untouched every key a human has already translated.

locales/en.json   + "checkout.cta": "Pay {amount} now"
                  ~ "cart.empty":   "Your cart is empty — keep browsing"

locales/it.json   + "checkout.cta": "Paga {amount} ora"
                  ~ "cart.empty":   "Il carrello è vuoto — continua a cercare"
locales/de.json   + "checkout.cta": "Jetzt {amount} bezahlen"
                  ~ "cart.empty":   "Dein Warenkorb ist leer — weiter stöbern"

Example output. If a translation drops or alters a placeholder, it is rejected and retried; if it still fails, the key is left for a human and listed in the job log.

Install in 2 minutes

Add your provider key as the repository secret AI_API_KEY, then save this as .github/workflows/ai-translate.yml.

.github/workflows/ai-translate.yml
# .github/workflows/ai-translate.yml
name: AI translate i18n
on:
  push:
    branches: [main]
  pull_request:
permissions:
  contents: write   # commits the updated locale files
jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.head_ref || github.ref_name }}   # commit back to the PR branch
      - uses: ./.github/actions/ai-translate
        with:
          ai-api-key: ${{ secrets.AI_API_KEY }}
          source: locales/en.json
          languages: it                                    # Pro: it,de,fr,... in one run
          # docs: docs/*.md                               # -> docs/it/
          # ai-base-url: ${{ secrets.AI_BASE_URL }}       # optional, any OpenAI-compatible endpoint
          # ai-model: ${{ secrets.AI_MODEL }}             # optional, e.g. gpt-4o-mini
          # license-key: ${{ secrets.LICENSE_KEY }}       # Pro: no limits + glossary

Any OpenAI-compatible endpoint works (OpenAI, OpenRouter, Groq, a local server): set AI_BASE_URL and AI_MODEL as secrets if you don't use OpenAI's default. The free tier translates into one language; list more after adding a Pro key. The action lives in your repository: download ai-translate-action.zip, unzip it into .github/actions/ and commit the .github/actions/ai-translate folder, or run from your repository folder:

mkdir -p .github/actions && curl -sL https://shop.lumnika.com/ai-translate-action.zip -o /tmp/a.zip && unzip -o /tmp/a.zip -d .github/actions

Free vs Pro

FreePro
Only new/changed keys, via .ai-translate-lock.jsonyesyes
Nested JSON locale files and Markdown docsyesyes
Placeholders ({name}, %s, ICU, HTML) preserved and verifiedyesyes
Strings per run100no limit
Target languages1no limit
Glossary (terms that must stay or be translated a fixed way)—yes
Pricefree$49 per year per organization

Get the Pro key

The license key is shown right after payment. Save it as the repository or organization secret LICENSE_KEY and uncomment the license-key line in the workflow. From the next push on: every language you list, no per-run limit, and your glossary applied.

$49 per year, per organization, no auto-renewal
Get the Pro key

🔒 Secure checkout by Stripe, your card details never touch our servers · 7-day money-back guarantee, no questions asked (deus@lumnika.com) · no account required.

Compared with translation platforms

Translation management platforms are built for teams with translators, reviewers and a workflow UI. If what you need is “the locale files are never behind the source”, here is what the entry plans cost (checked Oct 2026):

ToolEntry plan for software stringsPer year
LokaliseExplorer: $149/month, or $144/month billed yearly; 5 seats, up to 10 languages, 60,000 processed words/year≈ $1,728
CrowdinPro: from about $50/month billed yearly (about $59 monthly)≈ $600
Phrase StringsSoftware UI/UX: $525/month, billed yearly; 15 seats, 1M managed words≈ $6,300
AI Translate i18n BYOKPro license + your own AI tokens$49 + tokens

Sources: Lokalise pricing, Crowdin pricing, Phrase pricing, checked Oct 2026. Plans change often: check their pages before deciding. These platforms do much more (translator UI, review workflows, over-the-air updates); this action does one job, in your repository.

What the tokens cost (BYOK)

Example: 2,000 keys × 5 languages = 10,000 translations, translated from scratch once. Assuming about 40 input tokens per string (the string, its key and its share of the batched instructions) and about 20 output tokens:

Model (price per 1M tokens in / out)Whole project, 5 languages
gpt-4o-mini on OpenAI ($0.15 / $0.60)0.4M × 0.15 + 0.2M × 0.60 = ≈ $0.18

After the first run only new or changed keys are sent, so a typical PR costs a fraction of a cent. Even at three times these token estimates, a full 5-language translation stays under $1. Price from OpenAI API pricing, checked Oct 2026. On private repositories the job also uses your GitHub Actions minutes.

FAQ

Will it overwrite translations a human fixed by hand?
No. The lock file records the hash of the source string each translation came from; a key is re-translated only when its source text changes. Edit it.json by hand and the action leaves your wording alone.
What happens to placeholders and HTML?
They are protected before the call and checked after it: every {name}, %s/%d, ICU {count, plural, …} branch and HTML tag in the source must be present in the translation. A string that fails the check is retried once, then skipped and reported instead of committed broken.
Where do my strings go?
Only to the AI provider you configured, from your own runner. The Pro license check receives only the license key and the repository name; your strings and your AI key never pass through us.
Push or pull request: what does it do on each?
On a push it commits the updated locale files to the branch. On a pull request it commits to the PR branch, so reviewers see source and translations in the same diff (forks without write access just get the result in the job log).
What if the license check fails or the key is missing?
The action falls back to the free mode (100 strings, 1 language). It never fails your build because of the license.
One key for how many repositories?
One key per organization: save it once as an organization secret and use it in its repositories.
Is this a subscription?
No auto-renewal: $49 buys a key valid for one year, and you buy a new one only if you want another year. You only pay your AI provider for the tokens you use.
Is it on the GitHub Marketplace?
Marketplace listing coming soon. Until then the action is a zip you unzip into .github/actions/, free and Pro alike.

Get the Pro key — $49/year

Translating a WordPress site rather than a codebase? The AI Translate BYOK WordPress plugin adds a one-click Translate button to the post editor, with the same bring-your-own-key model.