Internationalization

English and Chinese resources with runtime locale switching.

The Kotlin template localizes user-facing text with Android string resources: values/strings.xml for English and values-zh/strings.xml for Chinese. Runtime language switching is handled in Compose without restarting the activity.

What it provides

SurfaceStatusImplementation
English resourcesIntegratedapp/src/main/res/values/strings.xml
Chinese resourcesIntegratedapp/src/main/res/values-zh/strings.xml
Runtime switchIntegratedLocaleController + LocalizedAppHost
PersistenceIntegratedDataStore key language_tag
Picker labelsIntegratedAppLanguage enum with localized label resource ids

Key files

How switching works

LocaleController maps the DataStore language_tag string into an AppLanguage:

enum class AppLanguage(val tag: String, val labelResId: Int) {
    English("en", R.string.language_english),
    Chinese("zh", R.string.language_chinese)
}

MainActivity wraps the app with LocalizedAppHost. The host creates a localized Context using Locale.forLanguageTag(language.tag), then provides that context and configuration through Compose locals:

LocaleController.selectedLanguage
  -> LocalizedAppHost
  -> LocalContext / LocalConfiguration
  -> stringResource(...)

Because the localized context is provided inside the composition, changing the language updates visible Compose strings in-session without an activity restart.

Resource rule

Put all user-visible copy in resources:

<string name="notifications_title">Notifications</string>

Then read it from Compose:

Text(stringResource(R.string.notifications_title))

Avoid hardcoding screen labels, button text, validation messages, and demo copy inside composables. The current Component gallery catalog is one area to audit if you want every demo title and summary localized too: its catalog entries are plain Kotlin strings.

Add a language

Add a resource folder

Create a new Android resource folder, for example:

app/src/main/res/values-ja/strings.xml

Copy the English keys and translate every value.

Add an enum case

Extend AppLanguage:

Japanese("ja", R.string.language_japanese)

Also add language_japanese to every existing strings.xml.

Rebuild and test

Run the app, open the drawer language picker, switch languages, and verify visible strings update without leaving the current screen.

Verify

  • Every key in values/strings.xml exists in values-zh/strings.xml.
  • No product-facing copy is hardcoded in feature screens.
  • The drawer language picker persists across app restarts.
  • Switching language updates nested screens and dialogs, not only top-level tabs.
  • Release-only strings such as Play review notes and legal URLs are handled outside the APK where appropriate.

On this page