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

# Localization

> Choose the language, override any string, and tune copy per country.

The SDK ships with copy in English, Spanish, Portuguese, French, Italian, German and
Russian. You can pick the language, let the user pick, and override any individual string.

<CodeGroup>
  ```swift iOS lines theme={null}
  let locale = ChmodKycConfiguration.Locale(
      defaultLanguage:         .es,   // .device .en .es .pt .fr .it .de .ru
      fallbackLanguage:        .en,   // Used when a string is missing in the default language
      allowsLanguageSelection: true,  // Shows the language picker inside the flow
      translations: [
          .init(language: .es, key: "welcome_title", value: "Verifiquemos tu identidad"),
          .init(language: .en, key: "welcome_title", value: "Let's verify your identity")
      ]
  )
  ```

  ```kotlin Android lines theme={null}
  val locale = SdkConfig.Locale(
      defaultLanguage = Language.es,   // DEVICE, en, es, pt, fr, it, de, ru
      fallbackLanguage = Language.en,  // Used when a string is missing in the default language
      allowLanguageSelection = true,   // Shows the language picker inside the flow
      texts = listOf(
          SdkConfig.Translation(Language.es, "welcome_title", "Verifiquemos tu identidad"),
          SdkConfig.Translation(Language.en, "welcome_title", "Let's verify your identity")
      )
  )
  ```
</CodeGroup>

## Choosing the language

<ParamField body="defaultLanguage" type="enum" default="DEVICE">
  `DEVICE` uses the device language when it is one of the supported seven, and falls back
  otherwise. Set an explicit language when your app already asks the user to choose one —
  a flow in a different language from the screen that launched it is jarring.
</ParamField>

<ParamField body="fallbackLanguage" type="enum" default="en">
  Used when a string is missing in the resolved language.
</ParamField>

<ParamField body="allowsLanguageSelection" type="boolean" default="true">
  Shows a language picker inside the flow. Worth keeping on for a broad consumer audience;
  turn it off when your app already owns that choice.
</ParamField>

## Overriding strings

Keys are lowercase with underscores and are **identical on Android and iOS**, so a copy
deck written once applies to both.

<Warning>
  An unknown key is ignored silently and the default copy is used. There is no error and no
  warning — a typo just means your override does nothing. Copy keys from the reference
  below rather than typing them from memory.
</Warning>

### Common keys

| Screen | Keys |
| - | - |
| Welcome | `welcome_title` `welcome_subtitle` `welcome_get_started` `welcome_step_document_title` `welcome_step_document_subtitle` `welcome_step_selfie_title` `welcome_step_selfie_subtitle` |
| Document type | `document_type_label` `document_country_label` `document_select_country` `document_type_national_id` `document_type_passport` `document_type_driver_license` `document_type_resident_permit` `document_type_temp_permit_id` |
| Instructions | `document_instruction_prepare_title` `document_instruction_prepare` `document_instruction_choose_title` `document_instruction_choose` `document_instruction_legible_title` `document_instruction_legible` `document_instruction_review_title` `document_instruction_review` `document_privacy_notice` |
| Scanning | `document_scan_title_front` `document_scan_title_back` `document_scan_instruction` `document_scan_start_button` `document_scan_capturing` `document_scan_permission` `document_scan_low_light` `document_scan_tap_to_focus` `document_scan_tip_lighting` `document_scan_tip_readable` `document_scan_tip_no_capture` `document_scan_feedback_blurry` `document_scan_feedback_glare` `document_scan_feedback_not_aligned` `document_scan_feedback_stabilizing` `document_scan_feedback_too_close` `document_scan_feedback_too_far` `document_scan_feedback_too_bright` `document_scan_feedback_too_dark` |
| Preview | `document_preview_title` `document_preview_instruction` `document_preview_confirm` `document_preview_retake` `document_preview_classifying` `document_preview_low_quality` `document_preview_mismatch` `document_preview_network_error` `document_preview_not_a_document` `document_preview_unreadable` `document_preview_unsupported` `document_preview_wrong_orientation` `document_preview_wrong_side` |
| Liveness | `liveness_title` `liveness_description` `liveness_check_start_button` `liveness_selfie_placeholder` `liveness_privacy_notice` `liveness_instruction_1_title` `liveness_instruction_1` `liveness_instruction_2_title` `liveness_instruction_2` `liveness_instruction_3_title` `liveness_instruction_3` |
| Processing and result | `verifying_identity` `almost_done` `processing_message` `processing_dont_close` `result_success_title` `result_success_message` `result_failure_title` `result_failure_message` `result_done_button` |
| Errors | `error_title` `error_message` `error_finish_button` `error_document_scan_max_retries` `document_verification_title` `document_verification_subtitle` `document_processing_error_title` |
| Common | `cancel` `close` `search` `select_language` |

<Info>
  A few scanning and preview keys exist only on Android — `document_scan_feedback_glare`,
  `document_scan_feedback_too_bright`, `document_scan_feedback_too_dark` and
  `document_preview_unsupported`. Setting them on iOS is harmless: unknown keys are ignored.
</Info>

## Country-specific overrides

Before falling back to the plain key, the SDK looks for `{key}_{country}` in lowercase.
This lets you tune a single string for one market without forking your whole copy deck:

<CodeGroup>
  ```swift iOS lines theme={null}
  .init(language: .es, key: "document_type_national_id",    value: "Documento de identidad"),
  .init(language: .es, key: "document_type_national_id_ar", value: "DNI")   // Argentina only
  ```

  ```kotlin Android lines theme={null}
  SdkConfig.Translation(Language.es, "document_type_national_id", "Documento de identidad"),
  SdkConfig.Translation(Language.es, "document_type_national_id_ar", "DNI")   // Argentina only
  ```
</CodeGroup>

This matters more than it looks for identity documents: the same `NATIONAL_ID` is a *DNI*
in Argentina, a *cédula* in Colombia and an *INE* in Mexico. Users recognise the local name
and hesitate at the generic one.

## Writing the copy

* **Say what to do, not what went wrong.** *Move the document closer* beats *Image too far*.
* **Keep it short.** These strings sit over a camera viewfinder, often read at arm's length.
* **Explain the selfie before it happens.** Use `welcome_step_selfie_subtitle` — users who
  are surprised by a face scan are the ones who abandon.
* **Test the longest language.** German and Spanish strings run noticeably longer than
  English and are where layouts break first.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.