> ## Documentation Index
> Fetch the complete documentation index at: https://hyperlocalise.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# i18n config

> Field-by-field guide for the i18n config file used by run, status, and sync commands.

## File overview

`i18n.yml` controls locales, file mapping, model profiles, and optional advanced routing. `i18n.jsonc` is still supported for compatibility.

## Starter config

```yaml theme={null}
locales:
  source: en-US
  targets:
    - es-ES

buckets:
  ui:
    files:
      - from: packages/ui/lang/{{source}}.json
        to: apps/web/lang/{{target}}.json

llm:
  profiles:
    default:
      provider: openai
      model: gpt-5.2
```

This is the shape written by `hyperlocalise init`.

When `groups` is omitted, Hyperlocalise automatically uses one implicit `default` group with:

* all locales from `locales.targets`
* all bucket names from `buckets`

## Locales

* `locales.source`: source locale.
* `locales.targets`: list of target locales.
* optional `locales.fallbacks`: fallback order per locale.

## Buckets

`buckets` map source files to target output templates.

Each file mapping uses:

* `from`: source path template
* `to`: target path template

Use `{{source}}`, `{{target}}`, and `{{localeDir}}` in templates. `{{localeDir}}` resolves to an empty segment when target equals source, and to the target locale otherwise.

### PHP array locale mapping patterns

Laravel-style locale arrays can be mapped directly when each file returns one static PHP array.

```yaml theme={null}
buckets:
  app:
    files:
      - from: resources/lang/en/messages.php
        to: resources/lang/{{target}}/messages.php
      - from: resources/lang/en/validation.php
        to: resources/lang/{{target}}/validation.php
```

Supported PHP locale files must begin with `<?php` and return a static `[...]` or `array(...)` literal. Hyperlocalise translates string leaves, flattens nested keys with dotted paths, and preserves comments, ordering, and array syntax when writing. Dynamic PHP such as variables, function calls, constants, `declare(...)`, or interpolated double-quoted strings is intentionally rejected.

Supported locale file extensions include `.json`, `.jsonc`, `.yaml`, `.yml`, `.php`, `.xml`, `.resx`, `.arb`, `.xlf`, `.xlif`, `.xliff`, `.po`, `.html`, `.liquid`, `.md`, `.mdx`, `.strings`, `.stringsdict`, and `.csv`.

YAML/YML locale files should be mapping-shaped files with string leaves. Nested mappings become dotted keys, sequences become `[index]` keys, and writeback rewrites existing string leaves while preserving key order/comments where possible. Mapping keys cannot contain `.`, `[`, or `]` because those characters are reserved for flattened paths. Non-string scalar leaves such as numbers, booleans, nulls, timestamps, anchors, and aliases are rejected to avoid silently corrupting metadata.

```yaml theme={null}
buckets:
  ui:
    files:
      - from: packages/ui/lang/{{source}}.yaml
        to: apps/web/lang/{{target}}.yaml
```

Generic XML mappings can point at non-Android XML locale files:

```yaml theme={null}
buckets:
  xml:
    files:
      - from: locales/en-US.xml
        to: locales/[locale].xml
```

XML entries must be text-only leaf elements keyed by `key`, `id`, or `name`, or nested path-shaped leaves. Android `<resources>` files, mixed-content XML, and CDATA-preserving writeback are not handled by the generic XML parser.

### CSV file mapping patterns

Use bucket file mappings to model CSV workflows.

Per-locale files:

```json theme={null}
{
  "from": "translations/en.csv",
  "to": "translations/[locale].csv"
}
```

Shared multi-locale file:

```json theme={null}
{
  "from": "translations/catalog.csv",
  "to": "translations/catalog.csv"
}
```

For shared multi-locale CSV files, keep one key column and one target locale column that `run` can update consistently.

### Fluent file mapping patterns

Use `.ftl` mappings for Mozilla Fluent locale files:

```json theme={null}
{
  "from": "locales/en-US/messages.ftl",
  "to": "locales/[locale]/messages.ftl"
}
```

Hyperlocalise supports Fluent messages, attributes, multiline values, and select/plural values as full translation units. Attributes use dotted keys such as `brand.title`. Fluent terms are not supported and fail during parsing.

### JS/TS locale module patterns

Use JavaScript or TypeScript locale module mappings when your app imports locale objects directly:

```yaml theme={null}
buckets:
  web:
    files:
      - from: apps/web/messages/{{source}}.ts
        to: apps/web/messages/{{target}}.ts
```

Supported modules must export one static object, for example:

```ts theme={null}
export default {
  home: {
    title: "Welcome",
    cta: "Start now",
  },
} as const;
```

Hyperlocalise preserves comments, imports, export syntax, and non-message module text. It rejects dynamic values, computed keys, spread properties, multiple exported locale objects, and interpolated template literals.

### Apple string catalog mapping patterns

Use `.xcstrings` mappings for Xcode string catalogs:

```json theme={null}
{
  "from": "ios/en.lproj/Localizable.xcstrings",
  "to": "ios/[locale].lproj/Localizable.xcstrings"
}
```

Hyperlocalise writes target values into `localizations[targetLocale]` and preserves catalog metadata. `status` and `check` read the requested target locale from the catalog. Variant and substitution source entries must include a source-language localization so Hyperlocalise can extract the source forms safely.

### Android XML string resource mappings

Android XML support is intentionally scoped to string resource files named `strings.xml` under `res/values*` directories. Use Android locale qualifier names in your target paths:

```yaml theme={null}
buckets:
  android:
    files:
      - from: app/src/main/res/values/strings.xml
        to: app/src/main/res/values-{{target}}/strings.xml
```

Supported resource entries are `<string name="...">` and `<plurals name="..."><item quantity="...">`. Resources marked `translatable="false"` are preserved and skipped. Unsupported translatable resource shapes such as `<string-array>` fail closed so they are not silently dropped.

### Java properties file mapping patterns

Use `.properties` mappings for Java resource bundles with one file per locale:

```yaml theme={null}
buckets:
  java:
    files:
      - from: src/main/resources/messages_{{source}}.properties
        to: src/main/resources/messages_{{target}}.properties
```

Supported entries are flat Java properties keys with string values. Hyperlocalise preserves comments, separators, and key order on write; translated values are written as escaped single-line `.properties` values.

## Groups

`groups.<name>` defines what to process together.

* `targets`: subset of `locales.targets`
* `buckets`: list of bucket names

`groups` is optional for beginner configs. Add it when you want to split execution by locale or file set.

## LLM profiles

`llm.profiles.<name>` fields:

* `provider`: `openai`, `azure_openai`, `anthropic`, `gemini`, `bedrock`, `lmstudio`, `groq`, `mistral`, or `ollama`
* `model`: provider model id
* `system_prompt` (optional): explicit system-message template
* `user_prompt` (optional): explicit user-message template
* `prompt` (deprecated, optional): legacy prompt template used as system fallback

Prompt variables:

* `{{source}}`
* `{{target}}`
* `{{input}}`

## Rules

`llm.rules` choose profile per group.

* `priority`: higher wins
* `group`: group name
* `profile`: profile name

`llm.rules` is optional. When no rule matches a group, Hyperlocalise falls back to `llm.profiles.default`.

## Hyperlocalise

`hyperlocalise` configures the public Hyperlocalise web API for `sync push` and `sync pull`.

* `project_id` (required unless `project_id_env` is set): Hyperlocalise project ID.
* `project_id_env` (optional): environment variable that contains the project ID.
* `api_base_url` (optional): API base URL. Defaults to `https://hyperlocalise.com/api`.
* `api_key_env` (optional): environment variable that contains the API key. Defaults to `HYPERLOCALISE_API_KEY`.
* `timeout_seconds` (optional): HTTP timeout for sync API calls. Defaults to `1200`.

`sync push` uploads source files. `sync pull` downloads translated files reconstructed by the API. Translation jobs are created by Hyperlocalise automation or in the web app, not by the CLI.

## Cache

`cache` configures the remote caching client.

* `enabled` (optional): enable remote caching for `run`.
* `endpoint` (optional unless `enabled=true`): remote cache service endpoint.
* `project_key_env` (optional unless `enabled=true`): environment variable that contains the project cache key.
* `timeout_seconds` (optional): remote cache request timeout in seconds.

## Advanced example

```yaml theme={null}
locales:
  source: en-US
  targets:
    - fr-FR
    - es-ES
  fallbacks:
    fr-FR:
      - es-ES
      - en-US

buckets:
  ui:
    files:
      - from: packages/ui/lang/{{source}}.json
        to: apps/web/lang/{{target}}.json
  docs:
    files:
      - from: docs/{{source}}/**/*.mdx
        to: docs/{{target}}/**/*.mdx

groups:
  app:
    targets:
      - fr-FR
      - es-ES
    buckets:
      - ui
  docs:
    targets:
      - fr-FR
    buckets:
      - docs

llm:
  profiles:
    default:
      provider: openai
      model: gpt-5.2
    docs_review:
      provider: openai
      model: gpt-5.2
      system_prompt: You are a senior technical translator.
      user_prompt: |-
        Translate from {{source}} to {{target}}.

        Keep Markdown and MDX syntax intact.

        {{input}}
  context_memory:
    provider: openai
    model: gpt-5.2
  rules:
    - priority: 100
      group: docs
      profile: docs_review

hyperlocalise:
  project_id: project_123
  api_base_url: https://hyperlocalise.com/api
  api_key_env: HYPERLOCALISE_API_KEY
  timeout_seconds: 1200

cache:
  enabled: true
  endpoint: dns:///cache.internal:443
  project_key_env: HYPERLOCALISE_CACHE_PROJECT_KEY
  timeout_seconds: 5
```

## Generate a starter

```bash theme={null}
hyperlocalise init
```

Then edit the generated `i18n.yml` for your project.

## Validation tips

* If you omit `groups`, every bucket runs for every target locale.
* Keep group targets inside `locales.targets`.
* Keep group buckets aligned with `buckets` keys.
* Keep profile names consistent between `profiles` and `rules`.
* Use `hyperlocalise` for `sync push` and `sync pull`.
* Keep `storage` for provider-specific TMS adapter configuration.
