A multilingual media, navigation, or messaging app can look finished on the phone and still greet drivers with English CarPlay tabs, Android Auto list rows, or truncated German labels on the head unit. The phone string catalog is not enough. CarPlay and Android Auto render template-driven UIs in a separate scene or car session, often with their own length limits and locale owner.
Treat automotive projection as a release surface: inventory it, translate it, rebuild it, and verify it alongside ordinary app strings.
Why head-unit copy drifts from the phone
Phone localization usually means extracting strings, translating them, shipping a binary or over-the-air update, and refreshing UI when the app language changes. Automotive projection adds another owner:
- CarPlay and Android Auto draw system templates. Your app supplies titles, rows, messages, and actions rather than a free-form view hierarchy.
- The CarPlay UI often runs in a dedicated scene. Hardcoded English in that controller never sees the phone localization pass.
- Android Auto may apply the host head-unit language rules, which can disagree with your in-app language picker.
- Glance time is short, so translations that fit a phone list row overflow or truncate on the car display.
- Locale changes on the phone do not always recreate the car session the way a cold reconnect does.
Apple's CarPlay framework documentation describes template-based apps that present content on the vehicle screen. CPListItem makes the contract explicit: your code supplies the primary and secondary text the system lays out. Apple's CarPlay developer landing page covers audio, messaging, navigation, and related categories, and notes that widgets and Live Activities can appear in CarPlay. If your release checklist only covers the phone target, those template strings stay English by default.
Build one automotive string inventory
Start with an inventory that phone, CarPlay, and Android Auto owners can share.
For each driver-facing label:
- Stable key shared across platforms when the meaning matches
- Phone string, if any, and whether it is too long for the car
- CarPlay surfaces that show it: tab title, list title, row text, empty state, now-playing accessory copy
- Android Auto surfaces that show it:
ListTemplaterows,MessageTemplatebody, grid labels, search prompts - Maximum rendered length guidance for translators
- Locale owner expectation: app-selected language, device language, or Android Auto host language
- Verification device: CarPlay simulator, Desktop Head Unit (DHU), or parked hardware
Map app locales to automotive testing locales deliberately. Do not assume that shipping de on the phone automatically proves the head-unit German path. Keep the inventory next to the ordinary catalog and reject releases that add a phone language without an automotive coverage plan.
Wire CarPlay through the same catalog as the phone
Practitioner reports show the common failure mode. A GitHub issue describes CarPlay strings such as "Podcasts", "Episodes", and "No Episodes" hardcoded in a CarPlay controller that runs in a separate scene, so they miss any future app-level localization pass. A 2026 Music Assistant mobile commit reports the same class of bug and routes CarPlay strings through a shared Compose catalog managed with the rest of the app, then exposes a resolver to Swift.
Use that pattern:
- Put CarPlay labels in the same String Catalog or shared
strings.xmlpipeline the phone already uses. - Prefix keys with a
carplay.orauto.namespace so translators see automotive context. - Resolve localized
Stringvalues before constructingCPListItem, list templates, or tab titles. PreferString(localized:)or your shared resolver over inline English literals. - Resolve CarPlay strings before the first template build, and rebuild or transactionally update templates after locale changes, because title and tab text are not a free-form phone View tree. The Music Assistant fix defers the first template build until strings load and calls out that CarPlay template titles are immutable once constructed.
- When tab labels change, follow Apple's tab-bar update model: adjust child template
tabTitlevalues and commit withupdateTemplates(_:), or replace the root template when a full rebuild is safer.
Include the CarPlay scene target in the same resource membership checks you already run for widgets and extensions. A catalog that exists only on the phone target reproduces English head-unit UI even when translators finished their work.
Respect Android Auto host locale ownership
Android Auto is not just "another Activity with the app locale." For apps built with the Android for Cars App Library, Android's Android for Cars releases state that on Android 13 and higher the locale of the Configuration provided by CarContext reflects the per-application language preferences for the host app, not that of your app. On Android 13+, CarContext configuration locale follows the Android Auto host app's per-app language preferences, not your app's setApplicationLocales value.
That sentence changes release testing. Your phone can show Dutch through per-app language preferences while the projected Auto UI still resolves strings from the host language configuration. Document the owner for each surface instead of filing false localization bugs against the phone picker.
Handle configuration callbacks honestly. Session.onCarConfigurationChanged runs after CarContext resources already match the new configuration, according to the Session reference. Use it to invalidate templates and rebuild screens from localized resources. Do not assume it recreates the whole car session the way a disconnect and reconnect does.
A Stack Overflow author reports exactly that gap: night and day uiMode changes call onCarConfigurationChanged, but language changes only apply after killing and restarting the Android Auto session. Treat that as a product and QA constraint. Tell drivers or support teams when a reconnect is required, and put reconnect checks on the localization test matrix.
Keep a shorter Auto and CarPlay copy deck
Head-unit UI is optimized for glances, not for phone paragraph length. A current Android Auto localization guide from LocaFlow stresses separate shorter Auto string resources, practical character budgets, and DHU locale testing. Keep a separate shorter CarPlay/Auto string inventory with length budgets and translator notes instead of reusing phone UI copy that truncates on the head unit.
Practical rules that survive translation expansion:
- Maintain
*_autoorcarplay_*keys even when the English source matches the phone string. - Put max-length notes in comments or TMS instructions: grid labels, row titles, and button actions need tighter budgets than phone settings screens.
- Prefer semantic density: "Recent trips" beats "View your recent trips and destinations".
- Test German and another long locale on the CarPlay simulator and DHU before you call the language done.
- For user-generated content such as playlist names or message previews, truncate on grapheme boundaries in your code rather than hoping the template ellipsis remains readable while driving.
Voice and search paths need the same inventory discipline. Media search queries arrive in the user's language; match against localized metadata rather than English-only indexes. Notification or message readback should avoid abbreviations that text-to-speech mispronounces in the target locale.
Verify phone language versus head-unit language
Build a checklist a QA owner can run without reading platform folklore:
- For each shipped locale, confirm CarPlay and Android Auto keys exist in the automotive inventory.
- Launch CarPlay simulator and DHU sessions after setting the phone language and, on Android 13+, the app language and host-relevant language conditions you support.
- Walk tabs, lists, empty states, error messages, and now-playing or navigation prompts.
- Change the phone language during an active session and record whether templates refresh, require a reconnect, or stay stale.
- Repeat with an in-app language picker that disagrees with the device language.
- Capture screenshots for the longest locale and one RTL locale.
- Confirm widgets or Live Activities that appear in CarPlay still resolve localized text from the correct bundle.
Document the expected language owner for the head unit in QA notes. If Android Auto follows host preferences while the phone follows setApplicationLocales, say so. That prevents "localization bug" tickets that are actually host-locale behavior.
Coordinate engineers, writers, and release owners
Assign one owner for automotive template strings and one owner for head-unit verification. Writers need length guidance and screenshots of the car UI. Engineers need shared resolvers, scene or session resource membership, and rebuild hooks. Release owners need evidence that CarPlay and Auto paths were exercised for every newly added phone language.
Put those checks on the same checklist that already covers widgets, watch companions, and store listings. Projection UI is where drivers notice English first because the phone never leaves their pocket.
How i18nAgent helps
i18nAgent already helps teams keep iOS and Android resource catalogs moving through reviewable translation workflows. Extend that pipeline to CarPlay and Auto keys instead of maintaining a second ad-hoc English-only controller. Keep automotive keys in the same project, mark them with clear namespaces, and require the head-unit matrix before you ship a new locale.
Validation checklist
- CarPlay scene and Android Auto module resolve strings from the shared catalog, not hardcoded English.
- Template construction waits for localized values and rebuilds after locale changes.
- Android QA records host-versus-app language ownership for Auto sessions.
- Translators receive length budgets for Auto and CarPlay keys.
- Simulator and DHU runs cover longest and RTL locales plus mid-session language changes.
Localizing the phone is necessary, but it is not sufficient for the head unit. Close the CarPlay and Android Auto gap with an explicit inventory, honest locale ownership, and verification that happens while the car session is alive.
The same stale-language problem shows up on the wrist; see how to localize companion watch apps without stale complications or tiles.
