Skip to content

Internationalization (i18n)

The SDK has a built-in i18n engine supporting 9 languages, accessible via classroom.i18n.

Built-in Languages

CodeLanguageNotes
zh-CNSimplified ChineseDefault language
zh-TWTraditional Chinese
enEnglish
jaJapanese
koKorean
viVietnamese
arArabicRTL layout handled automatically
idIndonesian
esSpanish

Specifying a Language

typescript
import { TencentClassroom } from '@tencent-classroom/sdk';

// Option 1: Specify at construction
const classroom = new TencentClassroom({ language: 'en' });

// Option 2: Switch at runtime
classroom.i18n.setLocale('ja');

// Query current language
classroom.i18n.getLocale(); // => 'ja'

// Check if RTL language (e.g. Arabic)
classroom.i18n.isRtl(); // => false (true for Arabic)

// Get all registered language codes
classroom.i18n.getSupportedLocales(); // => ['zh-CN', 'zh-TW', 'en', 'ja', 'ko', 'vi', 'ar', 'id', 'es']

Auto-detection

If language is not specified, the SDK calls detectSystemLocale() to automatically detect the browser language and map it to a supported locale code.

Using Translation Keys

typescript
// Single key lookup
classroom.i18n.t('uikit.footer.leave'); // => 'Leave Classroom'

// With interpolation parameters
classroom.i18n.t('uikit.member.online', { count: 5 }); // => '5 online'

Namespaces

SDK translation keys are organized into two namespaces:

NamespaceEnum ValueKey PrefixPurpose
SDKTI18nNamespace.SDKsdk.Internal error messages, TResult message fields
UIKitTI18nNamespace.UIKITuikit.UI component display text

Key format: {namespace}.{module}.{id}

Examples:

  • sdk.result.0 — SDK success message
  • sdk.result.20104 — SDK error "Camera not found"
  • uikit.footer.leave — UIKit "Leave Classroom" button
  • uikit.role.teacher — UIKit "Teacher" role name

Overriding Specific Keys

To customize certain texts (e.g., change "Teacher" to "Instructor"), there are two approaches:

Option 1: Override at Construction

typescript
const classroom = new TencentClassroom({
  language: 'en',
  // i18nOverrides: applies to the current language
  i18nOverrides: {
    'uikit.role.teacher': 'Instructor',
    'uikit.footer.leave': 'Exit Room',
  },
  // nameConfig: override per language
  nameConfig: {
    'zh-CN': { 'uikit.role.teacher': '讲师' },
    'en': { 'uikit.role.teacher': 'Instructor' },
  },
});

Option 2: Override at Runtime

typescript
classroom.i18n.setOverrides('en', {
  'uikit.role.teacher': 'Instructor',
  'uikit.footer.leave': 'Exit Room',
});

// Override other languages as well
classroom.i18n.setOverrides('zh-CN', {
  'uikit.role.teacher': '讲师',
});

Override Priority

Values from setOverrides / i18nOverrides take precedence over built-in translations. Overrides remain effective after switching languages.

Registering a New Language

To support a language not built into the SDK (e.g., Thai), use the following workflow. Use the base language (zh-CN or en) as a template, translate each value, then register.

Translation Workflow

  1. Call getLocaleMessages('en', TI18nNamespace.SDK) to get all SDK key list
  2. Call getLocaleMessages('en', TI18nNamespace.UIKIT) to get all UIKit key list
  3. Translate each value to the target language
  4. Register separately to each namespace via registerExtraLocale()

Get Built-in Key Templates

When registering a new language, you need to know all key names. Use classroom.i18n.getLocaleMessages() to retrieve a complete key map for any registered locale:

typescript
import { TI18nNamespace } from '@tencent-classroom/sdk';

// Get English SDK namespace keys (as a translation template)
const sdkMessages = classroom.i18n.getLocaleMessages('en', TI18nNamespace.SDK);
console.log(Object.keys(sdkMessages));
// => ['sdk.result.0', 'sdk.result.1000', 'sdk.result.1001', ...]

// Get English UIKit namespace keys
const uikitMessages = classroom.i18n.getLocaleMessages('en', TI18nNamespace.UIKIT);
console.log(Object.keys(uikitMessages));
// => ['uikit.footer.leave', 'uikit.role.teacher', ...]

// Get all namespaces merged (omit second argument)
const allMessages = classroom.i18n.getLocaleMessages('en');

// Get another locale for reference comparison
const zhMessages = classroom.i18n.getLocaleMessages('zh-CN');

Register the New Language

typescript
import { TencentClassroom, TI18nNamespace } from '@tencent-classroom/sdk';

const classroom = new TencentClassroom();
await classroom.init();

// ⚠️ Each namespace must be registered separately
// Register Thai translations for the SDK namespace
classroom.i18n.registerExtraLocale(TI18nNamespace.SDK, 'th', {
  'sdk.result.0': 'สำเร็จ',
  'sdk.result.20104': 'ไม่พบกล้อง',
  // ... more SDK keys
});

// Register Thai translations for the UIKit namespace
classroom.i18n.registerExtraLocale(TI18nNamespace.UIKIT, 'th', {
  'uikit.footer.leave': 'ออกจากห้องเรียน',
  'uikit.footer.mic': 'ไมโครโฟน',
  'uikit.role.teacher': 'ครู',
  // ... more UIKit keys
});

// Switch to Thai
classroom.i18n.setLocale('th');

Completeness Requirement

When registering a new language, provide translations for all keys in that namespace. Missing keys fall back to the default language (zh-CN).

Language Change Event

After a language switch, the SDK emits an event for UIKit components to refresh:

typescript
import { TEvent } from '@tencent-classroom/sdk';

classroom.on(TEvent.LANGUAGE_CHANGED, () => {
  // Language switched — UIKit components update automatically (Signal-driven)
  // Business layer can refresh custom text here
  console.log('Current language:', classroom.i18n.getLocale());
});

Switching Language via setConfig

In addition to classroom.i18n.setLocale(), you can also switch language via setConfig. Both have the same effect — choose either:

typescript
// Option 1: i18n.setLocale (directly calls the i18n engine)
classroom.i18n.setLocale('en');

// Option 2: setConfig (goes through the config system, auto-syncs to i18n engine)
classroom.setConfig({ language: 'en' });

Relationship Between the Two

setConfig({ language }) internally calls i18n.setLocale(language) and also updates state.config$. Using setConfig is convenient when updating multiple config fields simultaneously (e.g., debug, board, etc.).

Subscribe to language changes via state.config$:

typescript
classroom.state.config$.subscribe((config) => {
  console.log('Current language:', config.language);
});