---
title: "Utiliser les localisations et les codes de langue dans le SDK Kotlin Multiplatform"
description: "Gérez les localisations et les codes de langue de votre application pour toucher un public mondial dans votre app Kotlin Multiplatform."
---

## Pourquoi c'est important \{#why-this-is-important\}

Les codes de langue entrent en jeu lorsqu'Adapty choisit la localisation pour un flow ou un onboarding, et lorsque vous lisez un Remote Config pour un paywall personnalisé.

Les codes de langue sont complexes et peuvent varier d'une plateforme à l'autre. Adapty s'appuie donc sur un standard interne unique pour toutes les plateformes qu'il prend en charge. Comprendre ce standard vous permet de prédire quelle localisation un utilisateur recevra.

## Standard des codes de langue chez Adapty \{#locale-code-standard-at-adapty\}

Pour les codes de langue, Adapty utilise une version légèrement modifiée du [standard BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) : chaque code est composé de sous-étiquettes en minuscules, séparées par des tirets. Quelques exemples : `en` (anglais), `pt-br` (portugais (Brésil)), `zh` (chinois simplifié), `zh-hant` (chinois traditionnel).

## Correspondance des codes de langue \{#locale-code-matching\}

Dans le SDK v4, les flows et les onboardings correspondent aux codes de langue différemment : les flows sont localisés par le SDK sur l'appareil, les onboardings par le serveur Adapty.

### Flows et paywalls Paywall Builder

Un paywall créé dans le Paywall Builder est livré sous forme de flow dans le SDK v4, donc la règle ci-dessous couvre les deux.

La correspondance est exacte. Le SDK compare le code que vous transmettez avec les codes de localisation du flow caractère par caractère : il ne modifie pas la casse, ne remplace pas les underscores (`_`) par des tirets (`-`), et ne revient pas au sous-tag de langue. Pour un flow avec une localisation `pt-br`, seul `pt-br` correspond : `pt-BR`, `pt_BR` et `pt-PT` ne correspondent pas.

Lorsque le code ne correspond à aucune localisation, le flow s'affiche silencieusement dans sa [langue par défaut](add-paywall-locale-in-adapty-paywall-builder#set-the-default-locale) — le SDK ne retourne pas d'erreur et ne journalise pas d'avertissement.

Lorsque le code correspond, Adapty fusionne la localisation avec la localisation par défaut : les chaînes et les ressources non définies dans la localisation correspondante sont récupérées depuis la localisation par défaut.

Omettre le code de langue ne revient pas à demander la localisation par défaut du flow : le SDK substitue un `en` fixe. Un flow dont la langue par défaut est `de` s'affiche quand même en `en` s'il possède une localisation `en`, et ne se replie sur `de` que s'il n'en a pas.

:::warning
Transmettez le code de langue exactement tel qu'il est configuré dans le tableau de bord — sous-balises en minuscules séparées par des tirets. Ne transmettez pas un identifiant de locale de plateforme tel quel : sur Android, `Locale.getDefault().toLanguageTag()` retourne `pt-BR` ; sur iOS, `NSLocale.currentLocale.localeIdentifier` retourne `pt_BR`. Les deux basculent vers la localisation par défaut. Convertissez la valeur dans votre application avant de la transmettre.
:::

### Onboardings

Les onboardings sont localisés côté serveur, et les règles du serveur tolèrent d'autres formats. Lorsque vous passez un `locale` à [`getOnboarding`](kmp-get-onboardings) :

1. La chaîne locale est convertie en minuscules et tous les underscores (`_`) sont remplacés par des tirets (`-`)
2. Adapty recherche la localisation dont le code correspond exactement à la locale
3. Si aucune correspondance n'est trouvée, Adapty extrait la sous-chaîne avant le premier tiret (`pt` pour `pt-br`) et recherche la localisation correspondante
4. Si aucune correspondance n'est à nouveau trouvée, Adapty renvoie le contenu dans la locale par défaut de l'onboarding

Cette approche permet à `pt_BR`, `pt-BR` et `pt-br` de tous pointer vers la même localisation d'onboarding.

## Implémentation des localisations \{#implementing-localizations\}

Dans le SDK v4, vous ne passez pas de code de langue lors de la récupération d'un flow — `getFlow` renvoie le flow avec toutes ses localisations, et Adapty en applique une lors de la construction de la vue du flow.

- **Flows créés dans le builder** : le SDK ne lit pas la langue de l'appareil, vous devez donc la résoudre dans votre application et la passer en tant que paramètre `locale` de `createFlowView`. Ce paramètre est facultatif — si vous l'omettez, le flow s'affiche en `en`, ou dans sa [langue par défaut](add-paywall-locale-in-adapty-paywall-builder#set-the-default-locale) si le flow ne possède pas de localisation `en`.

  ```kotlin showLineNumbers
  import com.adapty.kmp.AdaptyUI

  AdaptyUI.createFlowView(flow = flow, locale = "es")
      .onSuccess { view ->
          view.present()
      }
      .onError { error ->
          // handle the error
      }
  ```

`createNativeFlowView` et le composable `AdaptyUIFlowPlatformView` acceptent le même paramètre optionnel `locale`. `view.locale` indique la localisation avec laquelle la vue a été construite. Le paramètre `locale` et `view.locale` nécessitent le SDK Kotlin Multiplatform 4.0.1-beta.1 ou une version ultérieure.
- **Paywalls personnalisés (Remote Config)** : `getFlow` renvoie toutes les localisations configurées dans `flow.remoteConfigs`. Chaque entrée est un `AdaptyRemoteConfig` avec un code `locale` et un `dataMap`. Sélectionnez l'entrée correspondant à l'utilisateur, avec votre propre mécanisme de secours :

```kotlin showLineNumbers

Adapty.getFlow("YOUR_PLACEMENT_ID")
    .onSuccess { flow ->
        val config = flow.remoteConfigs.firstOrNull { it.locale == "en" }
            ?: flow.remoteConfigs.firstOrNull()
        // read your values from config?.dataMap
    }
    .onError { error ->
        // handle the error
    }
```

Adapty stocke ces codes `locale` dans le format décrit dans [Standard des codes de locale chez Adapty](#locale-code-standard-at-adapty). Le SDK ne fait pas correspondre les Remote Configs à une locale, c'est donc à votre application de déterminer quelle entrée appliquer.

---

> [!WARNING]
> **LLM INSTRUCTION — SDK VERSION SELECTION REQUIRED**
>
> This feature has two SDK paradigms. Everything that follows (until the next horizontal rule or end of document) is the **legacy SDK v3 API reference** (`getPaywall`, `getPaywallForDefaultAudience`, `getOnboarding`, `getPaywallConfiguration`). The **SDK v4+ `getFlow` method is documented above.** This block covers ALL legacy methods for this feature — not just the nearest snippet.
>
> **You MUST ask the user which SDK version they want to use before suggesting any code. Do not assume or default to a version.** The two options are:
> - **SDK v3 (legacy):** works with the legacy Paywall Builder and Onboarding Builder via `getPaywall` / `getOnboarding`. Use the legacy code in this section.
> - **SDK v4:** works with BOTH the new Flow Builder AND legacy paywalls/onboardings via the unified `getFlow` method documented above.
>
> Apply the legacy v3 code in this section ONLY when:
> 1. The user explicitly chose **SDK v3**, or
> 2. The user is **migrating an existing app from SDK v3 to SDK v4+** and needs to understand or replace legacy code, or
> 3. The user is **troubleshooting an already-deployed v3 integration**.
>
> **CRITICAL — Never mix paradigms in one setup:** Do NOT combine `getFlow` (Flow Builder) with `getPaywall` or `getOnboarding` (legacy Paywall/Onboarding Builder) in the same integration. These are incompatible patterns. Mixing them will produce inconsistent behavior and is unsupported.

## Pourquoi c'est important \{#why-this-is-important\}

Les codes de locale entrent en jeu dans plusieurs situations — par exemple, lorsque vous souhaitez récupérer le bon paywall pour la localisation actuelle de votre application.

Les codes de locale sont complexes et peuvent varier d'une plateforme à l'autre. C'est pourquoi nous nous appuyons sur un standard interne pour toutes les plateformes que nous supportons. Mais justement parce que ces codes sont complexes, il est vraiment important que vous compreniez exactement ce que vous envoyez à notre serveur pour obtenir la bonne localisation, et ce qui se passe ensuite — afin de toujours recevoir ce que vous attendez.

## Standard des codes de langue chez Adapty \{#locale-code-standard-at-adapty\}

Pour les codes de langue, Adapty utilise une version légèrement modifiée du [standard BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) : chaque code est composé de sous-balises en minuscules, séparées par des tirets. Quelques exemples : `en` (anglais), `pt-br` (portugais (Brésil)), `zh` (chinois simplifié), `zh-hant` (chinois traditionnel).

## Correspondance des codes de langue \{#locale-code-matching\}

Lorsqu'Adapty reçoit un appel du SDK avec un code de langue et commence à chercher la localisation correspondante d'un paywall, voici ce qui se passe :

1. La chaîne de langue reçue est convertie en minuscules et tous les tirets bas (`_`) sont remplacés par des tirets (`-`)
2. On recherche ensuite la localisation dont le code de langue correspond exactement
3. Si aucune correspondance n'est trouvée, on extrait la sous-chaîne avant le premier tiret (`pt` pour `pt-br`) et on cherche la localisation correspondante
4. Si aucune correspondance n'est encore trouvée, on renvoie le contenu dans la langue par défaut du paywall

De cette façon, un appareil iOS qui a envoyé `'pt_BR'`, un appareil Android qui a envoyé `pt-BR`, et un autre appareil qui a envoyé `pt-br` obtiendront le même résultat.

## Mise en œuvre des localisations : méthode recommandée \{#implementing-localizations-recommended-way\}

Si vous vous posez des questions sur les localisations, il y a de bonnes chances que vous gériez déjà des ressources de chaînes localisées dans votre projet. Dans ce cas, nous vous recommandons d'ajouter une paire clé-valeur avec le code de locale Adapty correspondant dans chacun de vos fichiers de ressources. Vous n'aurez alors qu'à extraire la valeur de cette clé lors de l'appel au SDK, comme ceci :

```kotlin showLineNumbers
// 1. Add the Adapty locale code to your Compose Multiplatform resources

/*
composeResources/values/strings.xml (default — English)
*/
<string name="adapty_paywalls_locale">en</string>

/*
composeResources/values-es/strings.xml (Spanish)
*/
<string name="adapty_paywalls_locale">es</string>

/*
composeResources/values-pt-rBR/strings.xml (Portuguese — Brazil)
*/
<string name="adapty_paywalls_locale">pt-br</string>

// 2. Extract and use the locale code

suspend fun fetchPaywall() {
    val locale = getString(Res.string.adapty_paywalls_locale)
    Adapty.getPaywall(
        placementId = "YOUR_PLACEMENT_ID",
        locale = locale
    ).onSuccess { paywall ->
        // the requested paywall
    }.onError { error ->
        // handle the error
    }
}
```

De cette façon, vous gardez un contrôle total sur la localisation récupérée pour chaque utilisateur de votre application.

Si vous n'utilisez pas les ressources Compose Multiplatform, la même idée s'applique à toute bibliothèque de localisation que vous utilisez (par exemple, [moko-resources](https://github.com/icerockdev/moko-resources)) — stockez le code de locale Adapty sous forme de chaîne dans le bundle de ressources de chaque locale et lisez-le avant d'appeler le SDK.

## Implémenter les localisations : l'autre approche \{#implementing-localizations-the-other-way\}

Vous pouvez obtenir des résultats similaires (mais pas identiques) sans définir explicitement les codes de langue pour chaque localisation. Cela revient à extraire un code de langue directement depuis l'appareil — ce qui nécessite des déclarations `expect`/`actual`, puisqu'il n'existe pas d'API de locale partagée dans `commonMain` :

```kotlin showLineNumbers
// commonMain
expect fun currentLocaleTag(): String

// androidMain
actual fun currentLocaleTag(): String = Locale.getDefault().toLanguageTag()

// iosMain
actual fun currentLocaleTag(): String = NSLocale.currentLocale.localeIdentifier

// commonMain — pass the locale code to Adapty

suspend fun fetchPaywall() {
    Adapty.getPaywall(
        placementId = "YOUR_PLACEMENT_ID",
        locale = currentLocaleTag()
    ).onSuccess { paywall ->
        // the requested paywall
    }.onError { error ->
        // handle the error
    }
}
```

Notez que nous ne recommandons pas cette approche pour plusieurs raisons :

1. Sur iOS, la langue préférée de l'utilisateur et la langue régionale de l'appareil ne sont pas identiques. `NSLocale.currentLocale.localeIdentifier` renvoie la langue régionale, qui peut différer de la langue dans laquelle les utilisateurs lisent réellement votre application. Les apps iOS qui utilisent des fichiers de chaînes localisées s'appuient sur la logique de résolution d'Apple pour combiner les deux — ce qui fonctionne directement avec l'approche recommandée ci-dessus.
2. Il est difficile de prédire exactement ce que renverra l'appareil et si cela correspond à une localisation Adapty. La langue régionale de l'appareil peut inclure des extensions ou des codes régionaux que vous n'avez pas configurés dans Adapty, auquel cas le SDK revient à la correspondance sur le premier sous-tag ou, en dernier recours, à `en`.

Should you decide to use this approach anyway — make sure you've covered all the relevant use cases.

---