i18n.json Configuration

Max Prilutskiy·Updated2 months ago·4 min read

i18n.json is the configuration file that controls the Lingo.dev CLI and CI/CD integrations. It defines which languages to translate, where translatable content lives, and which translation backend to use.

Minimal example

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.15",
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "ja"]
  },
  "buckets": {
    "json": {
      "include": ["locales/[locale].json"]
    }
  }
}

The $schema field enables IDE autocompletion and validation. The version field tracks the schema version for automatic migration compatibility.

Locale

The locale section defines the source and target languages:

{
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de", "ja"]
  }
}
Field Description
locale.source The language your source content is written in. All translations flow from this locale.
locale.targets Array of target languages. Each target produces a separate file (or section) depending on the bucket format.

Language codes follow the BCP 47 standard - en, en-US, es-ES, zh-Hans, and platform-specific formats like Android's en-rUS are all supported.

To list available locale codes:

npx lingo.dev@latest show locale sources   # Available source languages
npx lingo.dev@latest show locale targets   # Available target languages

Buckets

Buckets define file discovery patterns and processing rules. Each bucket key specifies a file format, and its value configures which files to include or exclude:

{
  "buckets": {
    "json": {
      "include": ["locales/[locale].json"],
      "exclude": ["locales/[locale]/internal.json"]
    },
    "markdown": {
      "include": ["docs/[locale]/*.md"]
    }
  }
}
Field Description
include Array of file patterns with [locale] placeholder. Supports glob wildcards (*).
exclude Optional. Array of patterns to skip during processing.
lockedKeys Optional. Keys whose values are copied from source without translation. See Key Locking.
ignoredKeys Optional. Keys excluded from translation entirely - they don't appear in target files. See Key Ignoring.
preservedKeys Optional. Keys initialized once from source, then protected from automatic updates. See Key Preserving.
injectLocale Optional. Keys where the target locale code is injected automatically.

Include patterns

Include patterns use the [locale] placeholder, which resolves to your configured locale codes at runtime:

  • locales/[locale].json → locales/en.json, locales/es.json
  • docs/[locale]/*.md → docs/en/*.md, docs/es/*.md

Recursive glob patterns (**/*.json) are not supported. Use explicit directory paths instead.

Custom locale delimiters

By default, locale codes in filenames use a dash (-) delimiter: en-US.json. To use underscores instead, pass an object with a delimiter field:

{
  "include": [
    "standard/[locale].json",
    { "path": "legacy/[locale].json", "delimiter": "_" }
  ]
}

This produces legacy/en_US.json instead of legacy/en-US.json.

Key path notation

The lockedKeys, ignoredKeys, and preservedKeys arrays use forward slash (/) notation for nested keys and asterisk (*) for wildcards:

{
  "lockedKeys": ["brand/name", "config/*"]
}

For the full list of supported bucket types, see Supported Formats.

Provider

The provider section configures a raw LLM provider for translation. This section is optional - when omitted, the CLI uses a localization engine on Lingo.dev.

{
  "provider": {
    "id": "openai",
    "model": "gpt-4o-mini",
    "prompt": "Translate the provided text from {source} to {target}."
  }
}
Field Description
provider.id Provider identifier: openai, anthropic, google, mistral, openrouter, or ollama.
provider.model Model name from the provider (e.g., gpt-4o-mini, claude-3-haiku).
provider.prompt System prompt. {source} and {target} are replaced with locale codes at runtime.
provider.baseUrl Optional. Custom API endpoint (required for Ollama: http://localhost:11434).

Engine connection

To route translations through a specific localization engine, add the engineId field:

{
  "engineId": "eng_SxjMwMsfOIsvV1wh"
}

When engineId is set, every translation request applies your engine's brand voice, glossary, instructions, and model configuration automatically. If omitted and LINGO_API_KEY is set, the CLI uses the default engine in your organization.

For the full setup guide, see Connect Your Engine.

Environment variables

Variable Required Description
LINGO_API_KEY For Lingo.dev Engine Your Lingo.dev API key.
LINGO_API_URL No Custom API base URL (for self-hosted or staging).
OPENAI_API_KEY For OpenAI provider OpenAI API key.
ANTHROPIC_API_KEY For Anthropic provider Anthropic API key.
GOOGLE_API_KEY For Google provider Google API key.
MISTRAL_API_KEY For Mistral provider Mistral API key.
OPENROUTER_API_KEY For OpenRouter provider OpenRouter API key.

Full example

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.15",
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de", "ja"]
  },
  "buckets": {
    "json": {
      "include": ["locales/[locale].json"],
      "lockedKeys": ["brand/name", "brand/tagline"],
      "ignoredKeys": ["internal/*"]
    },
    "markdown": {
      "include": ["docs/[locale]/*.md"]
    }
  },
  "engineId": "eng_SxjMwMsfOIsvV1wh"
}

Version migration

The CLI automatically migrates older i18n.json configurations to the latest schema version. It creates a backup of your current file, updates the schema, and preserves all settings. No manual intervention is required.

Next Steps

Supported Formats i18n.lock Connect Your Engine Setup