Key Locking

Lingo.dev CLI allows you to lock specific translation keys so their values remain identical across all languages. When you lock keys, the CLI excludes them from translation processing and copies the source values directly to all target files.

Setting Up Key Locking

Add lockedKeys to your bucket configuration in i18n.json:

{
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de"]
  },
  "buckets": {
    "json": {
      "include": ["locales/[locale].json"],
      "lockedKeys": ["system/component", "config/engine", "modules/processor"]
    }
  }
}

The lockedKeys array uses forward slash (/) notation to specify nested keys.

How Key Locking Works

During translation processing, Lingo.dev CLI:

  1. Identifies locked keys from your configuration
  2. Excludes them from translation — locked content never gets sent to AI models
  3. Copies source values directly to all target files
  4. Maintains consistency across all languages

Example workflow:

// locales/en.json (source)
{
  "welcome": "Welcome to our platform",
  "system": {
    "component": "Lingo.dev CLI",
    "processor": "Translation Engine"
  },
  "config": {
    "engine": "Lingo.dev Engine"
  }
}

With locked keys configuration:

{
  "lockedKeys": ["system/component", "system/processor", "config/engine"]
}

Generated Spanish translation:

// locales/es.json (generated)
{
  "welcome": "Bienvenido a nuestra plataforma",
  "system": {
    "component": "Lingo.dev CLI",
    "processor": "Translation Engine"
  },
  "config": {
    "engine": "Lingo.dev Engine"
  }
}

Only welcome gets translated, while locked keys remain identical to the source.

Without key locking, "Lingo.dev Engine" might be mistranslated to "Motor de Lingo.dev" in Spanish or "Lingo.devエンジン" in Japanese, which we don't want in this example.

Nested Key Paths

Use forward slash (/) notation to lock keys at any depth:

{
  "lockedKeys": [
    "system/engine/component",
    "modules/ai/processor",
    "config/translation/handler"
  ]
}

This notation works with complex nested structures:

// Source structure
{
  "system": {
    "engine": {
      "component": "Lingo.dev Engine"
    }
  }
}

The path system/engine/component locks the component name value.

Keys with Dots

Forward slash notation handles keys that contain dots in their names:

// Source with dotted key names
{
  "modules": {
    "ai.translation": "AI Translation",
    "content.processor": "Content Processor"
  }
}

Lock these keys with:

{
  "lockedKeys": ["modules/ai.translation", "modules/content.processor"]
}

Multiple Bucket Types

Different file formats can have different locked keys:

{
  "buckets": {
    "json": {
      "include": ["locales/[locale].json"],
      "lockedKeys": ["config/engine", "system/component"]
    },
    "yaml": {
      "include": ["translations/[locale].yml"],
      "lockedKeys": ["service/name", "module/title"]
    }
  }
}

Each bucket type maintains its own locked keys list based on the content structure.