Skip to content
reception

Search documentation

Loading documentation…

    Log in
    Browse documentation

    Customization

    Language and localization

    The SDK includes built-in chat text for 48 languages and regional variants. It follows your app’s selected localization automatically, supports an override for your own language picker, and uses the same language matching as Reception’s push and review templates.

    View Markdown

    Automatic app language

    Leave Reception.shared.languageOverride at its default, nil, when your app uses iOS language selection. The SDK reads the first preferred localization from Bundle.main, then matches it to its supported languages. If no app localization is available, it uses English.

    This follows the host app’s selected localization. An English-only app stays English on a German device. To offer automatic German selection, your host app must include German among its supported localizations. The SDK’s bundled translations do not add localizations to your app.

    The device’s reported locale comes separately from Locale.current.identifier; its region is a device setting, not physical location. The SDK does not choose chat language directly from the device’s preferred-language list. Setting a SwiftUI .environment(\.locale, ...) on your own view is also not the SDK’s language-selection API: use the override for custom in-app selection.

    On Android

    Leave Reception.languageOverride at null on Android too. The SDK takes the app’s language from the first of these that applies:

    1. The app’s per-app language, set through the system’s app language settings on Android 13 and later, or with AppCompat’s AppCompatDelegate.setApplicationLocales on any version.

    2. On Android 13 and later, when the app declares its languages with android:localeConfig, the first of the phone’s languages that the app declares. An English-only app that declares only English stays English on a German phone, as on iOS.

    3. Otherwise the phone’s first language.

    So an app without android:localeConfig gets the chat in the phone’s language even when the app itself is only in English. Declare the app’s languages, or set languageOverride, if the chat should follow the app instead:

    res/xml/locales_config.xml
    <locale-config xmlns:android="http://schemas.android.com/apk/res/android">
        <locale android:name="en" />
        <locale android:name="de" />
    </locale-config>

    Reference the file with android:localeConfig="@xml/locales_config" on <application>. Expo projects that generate android/ with prebuild list the languages in expo-localization’s supportedLocales plugin option instead; prebuild writes both. The 48 bundled languages ship inside the SDK’s code, not as Android resources, so Google Play’s language splits never remove them and languageOverride works for every language. The matching rules below are the same on Android.

    Override the language

    Reception.shared.languageOverride

    The public property is @MainActor public var languageOverride: String? { get set }. Set a BCP 47 language tag such as fr-CA, pt-BR, or zh-Hant. The default is nil.

    For an existing custom language picker, restore its saved selection at startup, before presenting support. Apply every later selection change too. The host app owns persistence; the SDK does not save this setting across launches. There is no need to add a separate support-language picker.

    After your normal Reception configuration, restore the saved language selection (nil for automatic mode). This helper belongs in your app’s startup integration:

    Swift
    import Reception
    
    @MainActor
    func restoreSupportLanguage(_ savedAppLanguage: String?) {
        Reception.shared.languageOverride = savedAppLanguage
    }

    Put these assignments in the main-actor handlers for your existing language picker. Each line represents a separate selection:

    Swift
    // The user selects Canadian French.
    Reception.shared.languageOverride = "fr-CA"
    
    // The user later selects Arabic.
    Reception.shared.languageOverride = "ar"
    
    // The user returns to automatic app-language selection.
    Reception.shared.languageOverride = nil

    On Android, assign Reception.languageOverride = "fr-CA" and null for automatic selection; apps that use AppCompat’s per-app languages need no override, since the SDK follows them.

    Use nil, not an empty string or "system", for automatic selection. Invalid identifiers resolve to English. A language override changes the SDK; your app must update its own UI separately.

    Changing the override updates built-in labels, default appearance text, the chat’s locale and layout direction, and translations from the active remote appearance snapshot. It does not translate custom strings you already assigned. Language configuration survives Reception.shared.logout() within the running app; update it yourself when an account change also changes your app’s language preference.

    Server synchronization

    Selecting a language does not register a device by itself. Registration includes the current app language when support starts. Once support has started, language changes synchronize through device updates while the app is active, with retries after failures and later lifecycle updates.

    The dashboard, push delivery, and review templates use the last successfully reported app language. An offline change can update the chat immediately while the server still uses the previous language. The server uses the new language after a successful device update.

    The reported app tag is separate from the matched built-in language. For example, es-MX remains the reported app language while the SDK uses es-419 text. A valid unsupported tag such as is-IS remains reportable even though built-in text falls back to English.

    Supported languages

    The SDK supports these 48 language identifiers. Use the identifier in code; names are included for readable language menus. Regional entries are distinct translations.

    IdentifierEnglish nameNative name
    enEnglishEnglish
    deGermanDeutsch
    frFrenchfrançais
    fr-CAFrench (Canada)français canadien
    esSpanishespañol
    es-419Spanish (Latin America)español latinoamericano
    itItalianitaliano
    pt-BRPortuguese (Brazil)português (Brasil)
    pt-PTPortuguese (Portugal)português europeu
    caCatalancatalà
    roRomanianromână
    nlDutchNederlands
    svSwedishsvenska
    daDanishdansk
    nbNorwegian Bokmålnorsk bokmål
    fiFinnishsuomi
    plPolishpolski
    csCzechčeština
    skSlovakslovenčina
    huHungarianmagyar
    slSlovenianslovenščina
    hrCroatianhrvatski
    elGreekΕλληνικά
    ukUkrainianукраїнська
    ruRussianрусский
    trTurkishTürkçe
    jaJapanese日本語
    koKorean한국어
    zh-HansChinese (Simplified)简体中文
    zh-HantChinese (Traditional)繁體中文
    zh-HKChinese (Hong Kong)中文(香港)
    thThaiไทย
    viVietnameseTiếng Việt
    idIndonesianBahasa Indonesia
    msMalayBahasa Melayu
    hiHindiहिन्दी
    bnBengali (Bangla)বাংলা
    guGujaratiગુજરાતી
    knKannadaಕನ್ನಡ
    mlMalayalamമലയാളം
    mrMarathiमराठी
    orOdiaଓଡ଼ିଆ
    paPunjabiਪੰਜਾਬੀ
    taTamilதமிழ்
    teTeluguతెలుగు
    urUrduاردو
    arArabicالعربية
    heHebrewעברית

    Regional matching and fallback

    Identifiers are trimmed and normalized, including underscores to hyphens and canonical casing. For example, fr_CA matches fr-CA. Language extensions do not select another translation: en-US-u-ca-gregory reduces to en-US for matching and reporting. Exact supported tags match first, case-insensitively. Otherwise these rules apply:

    App languageBuilt-in language selected
    French with region CAfr-CA
    Other French, including fr-BEfr
    Spanish with no region or region ESes
    Spanish with any other region, including es-MX and es-USes-419
    Portuguese with region PTpt-PT
    Other Portuguese, including plain pt and pt-AOpt-BR
    Chinese with explicit Hans script, even zh-Hans-HKzh-Hans
    Other Chinese with region HK or MO, including zh-Hant-MOzh-HK
    Remaining Chinese with Hant script or region TWzh-Hant
    Remaining Chinese, including plain zhzh-Hans
    Norwegian no, nn, or nb variantsnb
    Other supported base languages, such as de-AT or en-GBBase language: de or en
    Unsupported or malformed identifiers, such as is-IS, xx, or invalid!en

    An unsupported app language falls back to English; it does not try another language from the device’s preferences. The backend consults device locale only for older devices that have no reported app language. It does not use that legacy fallback when an unsupported app language is present.

    Built-in, local, and remote text

    Built-in text

    Keep the default appearance strings when you do not need custom copy. title, welcomeTitle, and welcomeText resolve to localized built-in values. Composer controls, connection and delivery labels, accessibility text, and the review button (“Rate on the App Store”, or “Rate on Google Play” on Android) also use SDK resources. On Android, the notification channel name “Support replies” is translated too.

    The English appearance defaults are “Support”, “Questions, feedback, or a bug?”, and “You're chatting directly with our team.” Assigning those English strings yourself makes them literal overrides; leaving the defaults untouched allows automatic localization.

    German UI with authored German example messages.

    German UI with authored German example messages.

    Japanese UI with authored Japanese example messages.

    Japanese UI with authored Japanese example messages.

    Custom local strings

    You own translations for strings assigned through Reception.shared.appearance. Store them in your app’s string catalog and resolve them using your app’s localization system. The SDK does not translate those values or your app’s support entry-point label.

    Put this helper alongside your app’s localization integration. Pass the bundle your app uses for the selected language, or .main for ordinary iOS app-language selection. Add the three keys to your app’s Localizable.xcstrings, with a source value and translations:

    Swift
    import Foundation
    import Reception
    
    @MainActor
    func applyCustomSupportCopy(from localizedBundle: Bundle) {
        Reception.shared.appearance.title = String(
            localized: "support.title", bundle: localizedBundle
        )
        Reception.shared.appearance.welcomeTitle = String(
            localized: "support.welcome.title", bundle: localizedBundle
        )
        Reception.shared.appearance.welcomeText = String(
            localized: "support.welcome.text", bundle: localizedBundle
        )
    }

    On Android, resolve the strings from your app’s resources, for example Reception.appearance.title = context.getString(R.string.support_title), with a context that uses the selected language.

    Call this at startup and again whenever your app’s selection changes. Set Reception.shared.languageOverride in the same selection handler. Setting the override alone does not change .main bundle lookup for your custom text. See Appearance for the complete local customization API.

    Remote translations

    With Reception.shared.usesRemoteAppearance enabled (the default), published remote text can override your local appearance strings. For each text field, the SDK checks the exact canonical app tag, then its matched built-in language, then keeps the local value. Matching translation keys is case-insensitive; blank or oversized remote values are ignored.

    For example, es-MX checks remote es-MX, then es-419. A German app with no German remote translation keeps its local German text even if an English remote translation exists. An unsupported app language can use remote text for its exact tag, or English through its matched fallback. Absent local overrides, the local value is the built-in translation.

    The dashboard’s language selector chooses which translation to edit or preview; it does not change a customer’s language. After the SDK downloads a published appearance, it applies it the next time the chat opens. Changing the app language can select another translation from the already active snapshot immediately. Set Reception.shared.usesRemoteAppearance = false on the main actor to use only local appearance. See Remote appearance for publishing and caching.

    Right-to-left layout

    Arabic (ar), Hebrew (he), and Urdu (ur) select right-to-left layout in ReceptionChatView; other supported languages select left-to-right layout. Regional tags that match those languages receive the same direction. The chat also receives a locale derived from the matched language for localized formatting.

    The SDK scopes these settings to its chat view. Your own navigation, support button, and other host UI still need your app’s normal localization and layout handling. Mixed-language messages retain their original text; switching direction does not translate them.

    The Arabic example below shows both sides of a conversation. Outgoing bubbles, incoming replies, the composer, and message alignment follow the selected layout direction. The messages are authored example content; changing the language does not translate messages.

    Arabic conversation in the real SDK. iOS 26 presentation with example messages.

    Arabic conversation in the real SDK. iOS 26 presentation with example messages.

    Push notifications and review requests

    Push titles, default sender text, photo descriptions and plural forms, and hidden-message copy use the server’s matched app language. Custom title/body templates apply only for that matched language; missing overrides use its built-in defaults. The optional custom sender name is shared across all languages. Reply text inserted into a notification remains the agent’s original text. See Push notifications.

    Review templates use the same server language matching. Each scenario uses its override for the matched language or its built-in translation; {app} in custom copy is replaced with the app name. The agent can edit the draft before sending. If the effective recipient language changes, the composer asks the agent to keep the draft or use the current language’s template. See Reviews.

    Verify and troubleshoot

    1. With the override set to nil, run an English-only host app on a device configured for German. Confirm that the chat remains English. Then test a host app localization supported by both your app and the SDK.

    2. Exercise your existing picker with fr-CA, es-MX, zh-Hant, and ar. Confirm labels, regional matching, and Arabic layout; return to nil and relaunch to verify your saved preference handling.

    3. If custom text stays in the old language, re-resolve and reassign all three local appearance strings. If unexpected copy appears, check the published remote translation or temporarily disable remote appearance in your development build.

    4. On a device that has used support, change language offline, then reconnect with the app active. Confirm that App language in the dashboard eventually reflects the selection; Device locale and Region can remain different.

    5. In your test project, inspect push and review previews for the matched language. Use a configured iPhone or Android device for push verification. On Android 13 and later, also check the per-app language in the system settings and an app with and without android:localeConfig. Check that a review draft survives a language change and requires explicit review before sending.

    If an identifier unexpectedly produces English, compare it with the table and matching rules above. Use the app’s selected tag rather than a display name such as "German". If only the dashboard or a push uses the old language, confirm that the device has successfully synchronized since the change. See Troubleshooting for connection checks.