This episode makes the application inclusive and global: the Semantics API and content descriptions, focus and screen reader support, localization with resources, RTL support, and locale-aware formatting.

A good application serves everyone — including users who use screen readers like TalkBack, and users from different languages and cultures. These two fields, accessibility and internationalization, are often considered after features are done. Episode 13 changes that order.
In Compose, accessibility works through the Semantics API: a description layer that TalkBack reads and uses for focus. Meanwhile, internationalization uses the same Android resources as traditional view applications.
Episode 13 covers Semantics, focus and screen readers, localization, RTL, and locale-aware formatting.
Decorative elements and images need a description so TalkBack can read them. contentDescription is the most basic path:
Icon(
painter = painterResource(R.drawable.ic_keranjang),
contentDescription = "Keranjang belanja"
)contentDescription tells TalkBack the meaning of an icon. For purely decorative icons that have no meaning, use an empty string: contentDescription = "" makes TalkBack skip them.
For custom components, clarify the meaning via the semantics modifier:
Modifier.semantics {
contentDescription = "Suhu sekarang"
stateDescription = "25 derajat"
}The semantics block describes the element to accessibility services. For elements that are truly decorative and must be skipped, use Modifier.clearAndSetSemantics {} — this also helps screen reader efficiency.
Grouped elements sometimes need to be read as a single unit:
Row(
modifier = Modifier
.clickable(onClick = onPilih)
.mergeDescendants()
) {
Icon(...)
Text("Opsi A")
}mergeDescendants() merges the children's descriptions into a single node — important for items that are entirely clickable, so TalkBack reads them at once.
TalkBack navigates with accessibility focus. The default order follows layout position, but it can be configured:
Modifier.focusProperties {
next = fokusBawah
}focusProperties sets the next and previous focus elements. For complex screens, make sure the focus order is logical — not just positional order.
Test the application with TalkBack from a device or emulator:
adb shell settings put secure enabled_accessibility_services com.google.android.marvin.talkbackadb shell settings put secure enabled_accessibility_services com.google.android.marvin.talkback enables TalkBack directly from the terminal. Swipe the screen to navigate focus and make sure every element is read clearly.
Localizable content is stored in values/strings.xml, not hard-coded in the code:
<resources>
<string name="salam">Halo</string>
<string name="kata_terima_kasih">Terima kasih</string>
</resources>Access it in Compose with stringResource:
Text(stringResource(R.string.salam))stringResource(R.string.salam) fetches the string matching the active locale. Storing text in resources enables translation without touching code.
Create values-en folders for English, values-ja for Japanese, and so on, each with its own translated strings.xml. Android automatically picks the file matching the device locale.
Languages like Arabic and Hebrew are read right to left. Compose supports RTL automatically: Row and Arrangement follow layoutDirection:
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Text("Awal")
Text("Akhir")
}Don't use absolute coordinates like padding(start = ...) that need manual flipping; use direction-aware Start and End. This way the layout shifts automatically in RTL locales.
Numbers, dates, and currency are formatted according to the locale with resources or java.text.NumberFormat:
val jumlah = stringResource(
R.string.harga,
hargaTerformat
)R.string.harga can contain a placeholder like "Harga: %1$s" filled with the locale-formatted price. Avoid displaying raw numbers; format them first so international users can read them.
Episode 13 made the application inclusive: the Semantics API with contentDescription and custom semantics, focus order and testing with TalkBack, localization through string resources, automatic RTL support following layoutDirection, and locale-aware formatting.
Key takeaways:
In episode 14 we will discuss testing Compose UI — composable unit testing, UI tests with the Compose testing framework, semantics assertions and test tags, and integration testing from the UI to the data layer.