Skip to main content

File overview

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

Starter config

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.
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.
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:
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:
{
  "from": "translations/en.csv",
  "to": "translations/[locale].csv"
}
Shared multi-locale file:
{
  "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:
{
  "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:
buckets:
  web:
    files:
      - from: apps/web/messages/{{source}}.ts
        to: apps/web/messages/{{target}}.ts
Supported modules must export one static object, for example:
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:
{
  "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:
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:
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.

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

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
  manifest_path: .hyperlocalise/jobs.json
  timeout_seconds: 1200

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

Generate a starter

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 jobs.
  • Keep storage for provider-specific TMS adapter configuration.