# 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](/content/en/docs/cli/large-projects/index.html). 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](https://tools.ietf.org/rfc/rfc5646.txt) 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](/content/en/docs/cli/key-locking/index.html). |
| `ignoredKeys`      | Optional. Keys excluded from translation entirely - they don't appear in target files. See [Key Ignoring](/content/en/docs/cli/key-ignoring/index.html). |
| `preservedKeys`    | Optional. Keys initialized once from source, then protected from automatic updates. See [Key Preserving](/content/en/docs/cli/key-preserving/index.html). |
| `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](/content/en/docs/cli/supported-formats/index.html).

## Provider

The `provider` section configures a raw LLM provider for translation. This section is optional - when omitted, the CLI uses a [localization engine](/content/en/docs/platform/engines/index.html) 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](/content/en/docs/platform/engines/index.html), add the `engineId` field:

```
{
  "engineId": "eng_SxjMwMsfOIsvV1wh"
}
```

When `engineId` is set, every translation request applies your engine's [brand voice](/content/en/docs/platform/brand-voices/index.html), [glossary](/content/en/docs/platform/glossaries/index.html), [instructions](/content/en/docs/platform/instructions/index.html), and [model configuration](/content/en/docs/platform/llm-models/index.html) 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](/content/en/docs/platform/connect-your-engine/index.html).

## 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](/content/en/docs/cli/supported-formats/index.html) [i18n.lock](/content/en/docs/cli/lockfile/index.html) [Connect Your Engine](/content/en/docs/platform/connect-your-engine/index.html) [Setup](/content/en/docs/cli/setup/index.html)
