A multilingual VPN, fitness, accessory, or utility app can look finished in every Activity and still greet users with English Control Center gallery names, English Action Button hints, English toggle value labels, or English Quick Settings tile text. That mismatch rarely means translators skipped a host string. Apple's ControlWidget configuration and Android's TileService own the chrome the OS draws. Host String Catalog membership does not paint those surfaces unless the widget extension and tile service ship localized resources the system can load.
Treat system toggles like any other release-critical UI. Inventory Control Center and Quick Settings chrome apart from the host and apart from home-screen widgets, localize gallery and runtime labels deliberately, and prove both surfaces after real Language and Region changes.
Why Control Center and Quick Settings drift from the app language
A quick toggle has two owners. The container app owns onboarding, settings, and account state. The operating system hosts the control in Control Center, on the Lock Screen, or beside the Action Button, and hosts Android tiles in the Quick Settings panel. Apple's Creating controls to perform actions across the system article describes controls that perform actions or switch state from those system spaces, configured with SwiftUI strings and icons the system displays. The system loads a control from the widget extension when someone adds it from the controls gallery. Android's Create custom Quick Settings tiles guide explains that a TileService becomes the interface for a tile only after the user adds it, with a resource-backed android:label and runtime updates through setLabel, setSubtitle, and related fields.
The localization gap shows up in six places:
- Host UI strings live in the app target's catalog. Gallery names, control descriptions, Action Button hints, and toggle value labels often live only in the widget-extension target that defines the
ControlWidget. - Home-screen WidgetKit timelines can already be translated while Control Center chrome still uses English literals, because Control Center controls are a different API surface from home-screen widgets.
- Android manifest
android:labelvalues and runtimeTile.setLabel/setSubtitlestrings resolve from the service package resources, not from whatever Activity the user last opened. - Add-tile prompts such as
requestAddTileServiceshow an app-supplied label in a system dialog that users see before the shade ever opens. - Compact system chrome truncates long translations. Apple notes that Control Center size changes can hide title and value text; Android documents an 18-character guidance limit for default tile labels.
- Hardcoded English literals such as "Omi Mic", "Muted", "Live", or "Quick connect" never reach translators when they never lived in a catalog the extension or service loads.
Practitioner materials line up with that split. A public Omi feature request proposes an iOS 18+ mute ControlWidget whose sample code uses English literals for the intent title, toggle title, value labels, .displayName("Omi Mic"), and .description(...) inside the existing widget-extension target (Control Center mute ControlWidget proposal). That is library- and product-specific evidence that Control Center chrome is authored as its own surface and is easy to ship untranslated when the sample starts in English. ProtonVPN's open-source QuickTileService resolves tile labels through R.string resources and ships German translations such as quickConnect to "Schnellverbinden" and tileConnected to "Verbunden: %1$s" in values-de/strings.xml. Those reports describe specific projects, not a universal OS defect. They still surface the inventory questions your workflow must answer.
General iOS localization guides, including Phrase's iOS localization overview and the live i18nAgent iOS guide, cover catalogs and UI strings. They do not connect ControlWidget gallery localization to Action Button hints and Android TileService labels. The Android localization guide likewise stops short of Quick Settings shade labeling. Home-screen widget refresh after language changes, App Intents shortcut phrases, and launcher shortcuts covered elsewhere are different problems: a WidgetKit timeline or Siri phrase is not the Control Center gallery entry or Quick Settings tile the OS hosts.
Build a Control Center and Quick Settings string inventory
Localize ControlWidget displayName, description, Action Button hints, and value labels in the widget extension catalog: host-app String Catalog membership does not paint Control Center gallery chrome.
For each control or tile string, record:
| Field | Why it matters |
|---|---|
| Stable key | Shared meaning across iOS control and Android tile when the role matches |
| Apple surface | Controls gallery displayName, configuration description, Action Button hint, toggle/button value label, privacy-sensitive status text |
| Android surface | Manifest android:label, runtime label, subtitle, content description, add-tile prompt label |
| Bundle owner | Widget-extension target for ControlWidget, TileService package / module for Quick Settings |
| System metadata | Control kind identifiers, QS tile component names, active/toggleable metadata that is not user-visible but still couples to labeled surfaces |
| Fallback | Base localization that remains English-complete without masking missing translations in QA |
| Verification | Device Language and Region, per-app language, Control Center edit mode, Quick Settings edit mode, cold start after language change, expanded German/French labels |
Apple's Adding refinements and configuration to controls article tells you to customize the control name with displayName and to localize that name when applicable, and to add a localizable description for the configuration view. The displayName(_:) and description(_:) modifiers take LocalizedStringResource. controlWidgetActionHint(_:) likewise takes a LocalizedStringResource for the Action Button hint. Put those strings in the widget-extension catalog with translator notes that the string appears in compact system chrome and must stay short. A shared host catalog is not enough on its own. Xcode target membership for the extension and Android res/values-*/ packages for the tile module are part of the localization contract.
Localize Android tile labels and add-tile prompts on purpose
Treat Android TileService manifest labels, runtime setLabel and setSubtitle strings, and requestAddTileService prompt copy as first-class localization surfaces with short-label length checks.
Declare the service with a resource-backed label rather than a hardcoded English word in the manifest. Android's Quick Settings guide shows android:label="@string/my_default_tile_label" and notes the short default-label guidance. In onStartListening or whenever state changes, resolve getString (or your localization layer) before calling setLabel, setSubtitle, and setContentDescription, then call updateTile. Active-mode tiles that call TileService.requestListeningState still need those updates to run after a language change, not only after the first install.
When you prompt users with requestAddTileService, pass a localized tileLabel. That dialog is often the first time someone sees the tile name. An English prompt next to a translated shade label, or the reverse, reads like an unfinished release even when the host app is complete.
Keep a length budget. German and French labels expand. If your English label already sits near the documented short-label guidance, give translators a maximum character note and a preferred shorter synonym. Subtitles help when the primary label must stay tiny, but only if the subtitle is also localized and verified on small devices.
Verify after device and per-app language changes
Re-verify Control Center and Quick Settings after real device language and per-app language changes because scheme language or a translated host Activity alone does not prove the control or tile resolves the right resources.
Xcode scheme Application Language can make the host look correct while Control Center still shows English gallery chrome if the widget extension never received the translated catalog. Android per-app language preferences can leave a TileService resolving default resources if the service process does not pick up the same locale configuration the Activity uses. Build a release checklist that includes:
- Fresh install in a non-English device language with the control or tile added from the system gallery or edit mode.
- Language change after the control or tile is already pinned, followed by a cold start and a forced reload where the platform provides one.
- Per-app language override that differs from the device language, then reopen Control Center and Quick Settings.
- Expanded translations (German and French at minimum) for gallery names, value labels, tile labels, and add-tile prompts.
- English fallback for a locale you intentionally do not ship, confirming missing keys do not render as raw key names in system chrome.
- Side-by-side comparison of host UI language, home-screen widget language, and Control Center / Quick Settings language on the same device.
On Apple platforms, remember that controls update when someone interacts with them, when the app asks to reload through ControlCenter, or when the system receives a relevant push. A translation drop that never triggers a reload can leave stale English labels visible until the next natural refresh. On Android, active tiles that only update on click can look fine in English during development and still ship stale labels after a language change if nothing requests a listening state.
Keep discoverability copy in the same release train
Controls and tiles are useless if users cannot find them. Gallery displayName and description are marketing-adjacent product copy living inside the widget extension. Android add-tile prompts and the default manifest label are the shade equivalent. Put those strings in the same sprint as the feature toggle, not in a "polish later" bucket after the English engineering sample lands.
Give translators context screenshots from Control Center edit mode and Quick Settings edit mode, not only from the host app. Note which strings appear beside system icons, which appear in a configuration sheet, and which appear as Action Button hints. Without that context, translators write full sentence descriptions that truncate into nonsense on the shade.
If the product ships both a home-screen widget and a Control Center control, keep naming aligned but inventory the strings separately. Widget titles and control gallery names drift quickly when different engineers own WidgetKit timelines and ControlWidget configurations.
Release gates that catch English system toggles
Before you call a locale done, require evidence that:
- The widget-extension String Catalog or
.lprojcontains everydisplayName,description, Action Button hint, and value label used by eachControlWidget. - The Android tile module contains translated resources for manifest labels, runtime labels, subtitles, content descriptions, and add-tile prompt labels.
- QA opened Control Center and Quick Settings on a device (or equivalent system UI) in the target language after a language change, not only inside the host Activity.
- Compact-chrome length review passed for German and French on the smallest supported phone class.
- Home-screen widget language and Control Center / Quick Settings language match the intended app language for the build under test.
Automate what you can. Fail CI when the widget-extension catalog lacks locales the host ships. Fail when TileService modules reference string resources missing in a required values-* folder. Still keep a manual system-UI pass. Emulators and scheme overrides miss process boundaries that only show up when the OS hosts the control.
What not to confuse with this workflow
Do not treat this as a second home-screen widget article. WidgetKit timeline localization after language changes remains a separate release surface. Do not reopen App Intents phrase localization or Android launcher shortcut labels here either. Those govern Siri discovery and long-press launcher menus, not Control Center gallery chrome or the Quick Settings shade. Share extensions, custom keyboards, and Autofill credential providers also own OS-hosted chrome, but their string inventories and Settings enablement paths are different products with different failure modes.
The durable rule is narrow: if the operating system draws a toggle your app supplies, that toggle's labels need an owner, a catalog, translator context, length limits, and a post-language-change verification step. Control Center and Quick Settings are simply where users notice first when that owner is missing.
