Internationalization

The SDK supports 80+ languages for UI text and error messages.

📘

This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation here. Contact your Incode Representative for upgrade information and check if you are a candidate for this upgrade.

Full rollout to all clients still TBD.


The SDK supports 80+ languages for UI text and error messages.

Setting the Language

Pass the lang property inside the i18n option when you call setup():

import { setup } from '@incodetech/web';

await setup({
  apiURL: API_URL,
  token: session.token,
  i18n: {
    lang: 'es', // Spanish
  },
});

If a language was previously stored by the SDK (for example, when a user picked one from a language selector), that stored choice takes precedence over lang. Treat lang as the default for first-time users, not a hard override.

How It Works

  • The lang property sets the UI language for all SDK components within the flow
  • Translations are loaded from Incode's CDN at runtime
  • Error messages and instructions are automatically translated
  • The language is also sent to the backend for server-side localization

Custom Translations

Provide your own translation strings through the i18n option in setup(). Pass a translations object keyed by language code, then by translation key.

import { setup } from '@incodetech/web';

await setup({
  apiURL: API_URL,
  token: session.token,
  i18n: {
    translations: {
      en: {
        phone: { verify: 'Verify your phone number' },
        email: { willSendCode: 'We will email you a one-time code.' },
      },
      es: {
        phone: { verify: 'Verifica tu número de teléfono' },
      },
    },
  },
});

By default, your strings merge on top of Incode's CDN translations, so you only override the keys you list. Any key you omit keeps its default text.

Keys use dotted, camelCase paths in the form module.description (for example phone.verify). Write them as nested objects (above) or as flat dotted keys:

translations: {
  en: { 'phone.verify': 'Verify your phone number' },
}

Use {{variableName}} for values the SDK fills in at runtime — keep the placeholder name unchanged:

translations: {
  en: { selfie: { retryAttempts: 'You have {{count}} attempts left.' } },
}

Translation values are rendered without HTML escaping. Never interpolate user-controlled input directly into a translation string — doing so can introduce a cross-site scripting (XSS) vulnerability. Keep translation values as static, trusted content.

Use only your own translations

To skip Incode's CDN and serve every string yourself, set skipRemoteLoad: true:

await setup({
  apiURL: API_URL,
  token: session.token,
  i18n: {
    skipRemoteLoad: true,
    translations: {
      en: {
        /* every string your flow displays */
      },
    },
  },
});

With skipRemoteLoad: true, any key you do not define renders the last segment of the key name in Start Case (for example, phone.verify renders as Verify). Provide a complete en bundle so the flow falls back to English for missing keys.

Load translations from your own endpoint

To serve translation files from your own host or CDN, set loadPath to a URL template. The SDK fetches one file per language, replacing {{lng}} with the language code and {{ns}} with the namespace (always default):

await setup({
  apiURL: API_URL,
  token: session.token,
  i18n: {
    loadPath: 'https://cdn.example.com/locales/{{lng}}/{{ns}}.json',
  },
});

For example, loading Spanish requests https://cdn.example.com/locales/es/default.json. Each file must be a JSON object of translation keys, using the same module.description structure shown above.

Setting loadPath replaces Incode's CDN entirely — the SDK loads translations only from your endpoint and never contacts Incode's remote. You do not need skipRemoteLoad for this; reserve that flag for the inline-only case above (in fact, skipRemoteLoad: true disables remote loading altogether and would stop loadPath from being fetched).

Supported Languages

The SDK loads translations from CDN at runtime for every code below.

CodeLanguage
enEnglish (default)
en-DGEnglish (Diego Garcia)
esSpanish
es-ESSpanish (Spain)
es-MXSpanish (Mexico)
es-419Spanish (Latin America)
ptPortuguese
pt-BRPortuguese (Brazil)
pt-PTPortuguese (Portugal)
frFrench
fr-CAFrench (Canada)
deGerman
itItalian
nlDutch
plPolish
ruRussian
ru-RURussian (Russia)
trTurkish
arArabic
ar-EGArabic (Egypt)
ar-AEArabic (UAE)
zhChinese (Simplified)
zh-CNChinese (China)
zh-TWChinese (Taiwan)
zh-HANTChinese (Traditional)
jaJapanese
ja-JPJapanese (Japan)
koKorean
ko-KPKorean (North Korea)
viVietnamese
idIndonesian
jvJavanese
thThai
th-THThai (Thailand)
hiHindi
bnBengali
neNepali
urUrdu
fa-IRPersian (Iran)
ukUkrainian
uk-UAUkrainian (Ukraine)
heHebrew
elGreek
el-GRGreek (Greece)
srSerbian
sr-LatnSerbian (Latin)
sr-YUSerbian (Yugoslavia)
hrCroatian
bsBosnian
slSlovenian
mkMacedonian
huHungarian
roRomanian
csCzech
cs-CZCzech (Czechia)
skSlovak
etEstonian
lvLatvian
ltLithuanian
da-DKDanish (Denmark)
fi-FIFinnish (Finland)
nb-NONorwegian Bokmål (Norway)
sv-SESwedish (Sweden)
caCatalan
msMalay
tlFilipino/Tagalog
tl-PHFilipino (Philippines)
cebCebuano
myBurmese
kmKhmer
loLao
kaGeorgian
azAzerbaijani
kkKazakh
kyKyrgyz
uzUzbek
mnMongolian
amAmharic
soSomali
swSwahili
af-ZAAfrikaans (South Africa)
htHaitian Creole
hmnHmong

See Also