Skip to main content

Keep Mobile Consent Forms in the App's Selected Language

2026-10-29

Keep Mobile Consent Forms in the App's Selected Language

Mobile app consent localization can fail even when every app-owned screen is translated. A user chooses French inside an English-language phone, opens a consent form, and sees English because the consent SDK follows the device language or a provider default. Recreating the form carelessly can create a worse problem by mixing language presentation with the user's stored privacy choices.

Fix the boundary with a locale adapter that treats consent language and consent state as separate data. The adapter maps the app's effective locale to a published provider language, applies an explicit fallback, and rebuilds only the presentation layer when language changes. The result is a privacy form that follows the app without resetting or reinterpreting consent.

Why the consent form drifts from the app

A consent management platform, or CMP, usually owns its message catalog, configuration console, runtime SDK, and saved consent model. Your app owns its language selector and string resources. Unless the integration connects those systems explicitly, they resolve language through different signals.

Google's instructions for European regulations messages in AdMob describe a default language plus additional languages. The message can match an additional language to the device language, and Google recommends selecting languages that match those in which the app is available. Apps that always follow the device can use this behavior. An independent in-app language choice needs explicit handling.

Language can also drift at publication time. A team may add a locale to the app but omit it from the provider console, translate the consent message without publishing it, or update the provider template after the mobile release. OneTrust's mobile SDK capability matrix lists translated text and publisher-triggered re-consent as separate capabilities. Treating them as separate controls prevents a wording release from becoming an accidental consent-state migration.

An older Google consent SDK issue reports an English consent form shown to non-English users. The report does not establish a defect in current UMP releases. It does show the user-facing failure clearly: privacy choices are hard to understand when the provider-owned form ignores the language in which the person is using the app.

Define one mobile app consent localization contract

Keep CMP-specific locale codes inside one adapter. The rest of the app should pass a canonical BCP 47 language tag and receive a complete resolution record.

ConsentLocaleResolution
  requestedLocale: "fr-CA"
  providerLocale: "fr"
  fallback: "language"
  messageRevision: "eu-consent-2026-09-10.2"
  presentationGeneration: 7

The fields have distinct jobs:

  • requestedLocale is the effective language selected by the app.
  • providerLocale is a language that has approved, published consent copy.
  • fallback explains whether the match was exact, language-level, or the product default.
  • messageRevision identifies the provider configuration and copy used for presentation.
  • presentationGeneration invalidates a form created under an earlier language or message revision.

Do not derive the requested locale from country, IP address, advertising region, SIM country, or billing profile. Those values may affect which legal message applies, but they do not reliably describe the language the user can read. Keep jurisdiction resolution and language resolution as two inputs to the CMP policy decision.

Build the provider mapping from languages that are both supported by the SDK and published in the provider console. A locale exposed in the app selector is not enough. If the app supports fr-CA but only reviewed fr consent copy exists, record the language-level fallback. If no French copy exists, use the approved product default and make that fallback visible in diagnostics and release tests.

Apply language before requesting presentation

Google's current Android UMP setup guide tells apps to request updated consent information at every launch, then load and show a form when required. Preserve that lifecycle while inserting locale resolution before any provider UI is created.

Use this sequence:

  1. Resolve the app's effective locale from the same source used by the current screen.
  2. Resolve jurisdiction and consent requirements through the provider's supported APIs.
  3. Map the app locale to an approved, published provider language.
  4. Configure the provider presentation locale when its public API supports an override.
  5. Request current consent information.
  6. Load or create the form only after locale and consent information are ready.
  7. Record requested locale, provider locale, fallback class, SDK version, and message revision.
  8. Present the form without copying its consent values into a language-specific store.

A provider may not offer a runtime locale override. In that case, document the actual behavior instead of pretending the adapter can change it. You may need a provider configuration designed around device language, a supported SDK upgrade, or an app-owned explanation before the form opens. Do not patch provider views, scrape labels, or replace text through private UI classes. Those approaches are brittle and can break accessibility or legal review.

The orchestration can remain provider-neutral:

prepareConsentSurface():
    requested = appLocale.current()
    policy = consentProvider.refreshConsentInfo()
    resolved = consentLocaleMap.resolve(
        requested,
        policy.messageType,
        publishedMessageManifest
    )

    consentProvider.configurePresentationLocale(resolved.providerCode)
    form = consentProvider.loadRequiredForm(policy)

    return ConsentPresentation(
        form = form,
        locale = resolved,
        consentStateId = policy.stableStateId
    )

The pseudocode fixes the ordering. Providers expose different methods, so wrap the installed SDK's public API behind the adapter and test its required call order.

Preserve consent state across language changes

A language change should invalidate localized presentation, not the underlying choice. Store consent by stable purpose, vendor, policy, and provider identifiers. Never key consent by translated button text, localized purpose names, array positions from a rendered form, or the locale used when the form opened.

When the user switches the app language:

  1. Close or dismiss any form created under the old locale if the provider allows safe dismissal.
  2. Increment the presentation generation and discard locale-derived form objects.
  3. Keep the provider's consent information and language-neutral choice identifiers intact.
  4. Resolve the new provider locale and recreate the presentation layer when another form is required or the user opens privacy options.
  5. Confirm that previously stored choices have the same semantic identifiers before and after recreation.

Do not force re-consent merely because the user selected another language. Re-consent belongs to a policy or message-version decision. The provider may trigger it after a material configuration publication, as OneTrust documents for its re-consent-on-publish capability, but the app should not imitate that transition for a cosmetic language refresh.

Language changes can happen while a form is loading. Bind every asynchronous load result to its presentation generation. If the app moves from English generation 7 to French generation 8, discard a late English result from generation 7 rather than presenting it over the French app.

Handle fallback, offline use, and partial failure

An approved fallback chain should be deterministic: exact language-script-region match, reviewed language-level match, then product default. Avoid a silent chain based on whichever provider bundle happens to load first.

If the selected provider language is unavailable, log the requested and resolved tags and show an app-owned notice when the difference would surprise the user. The notice should explain the language handoff without paraphrasing legal choices or replacing the provider form.

If consent information cannot be refreshed, follow the provider's documented rules for whether ads, tracking, or other controlled behavior may proceed. Do not infer permission from a network failure. Google's UMP guide separates consent-information refresh, form presentation, and privacy-options availability; keep those states explicit in application control flow.

Offline behavior needs a product decision. A previously stored consent state may remain available, while a new or revised form cannot be loaded. The app should distinguish known choice, form unavailable from no choice recorded. Queue a bounded retry when connectivity returns, keep restricted behavior restricted where required, and avoid displaying stale legal copy as though it were current.

A message publication can also race with a mobile session. Include the provider configuration or message revision in diagnostics. When the provider does not expose a revision identifier, record a release-managed expected revision and verify it with screenshots in a clean test environment.

Verify the complete consent lifecycle

Unit-test locale normalization, provider aliases, published-language filtering, fallback reasons, and presentation-generation invalidation. Integration tests should use a fake CMP adapter to prove that locale configuration happens before form loading and that a late result from an old generation is discarded.

Run the real provider SDK through this release matrix:

  • device language and app language match
  • app language differs from the device language
  • exact regional locale is available
  • only a reviewed language-level fallback is available
  • no requested-language copy is published
  • first launch requires consent
  • returning user has a stored choice
  • privacy options reopen after consent
  • app language changes before form loading completes
  • app language changes while the form is visible
  • provider message copy changes without an app update
  • provider publication intentionally requires re-consent
  • device is offline on first launch and on a later launch
  • right-to-left layout, screen-reader language, focus order, and large text
  • SDK upgrade in a release build

Commercial CMP pages such as consentmanager's mobile app consent overview show that mobile consent collection is a distinct deployment surface, not app-owned translation copy. Use such pages to identify the competing implementation scope, not as proof that a provider satisfies your locale contract.

A release passes only if the visible form matches the resolved provider locale, every app entry point opens the same current presentation, fallback is deliberate, stored purpose choices remain stable, and required re-consent follows the policy version rather than the language switch. Test screenshots should mask identifiers and avoid capturing user data.

Common implementation mistakes

Initializing the CMP once at process start freezes the language for apps that support runtime switching. Reading device language again inside the CMP integration bypasses the app's effective-locale resolver. Publishing a translated app build before publishing the matching provider message creates a deterministic fallback that can look like an intermittent SDK bug.

Tying consent semantics to presentation corrupts the contract. A localized title is reviewable copy, not a database key. A translated Accept label describes an action but does not identify the purposes selected. Stable provider and policy identifiers must drive storage, auditing, and server communication.

Avoid broad analytics payloads. Locale-resolution diagnostics need requested locale, resolved locale, fallback class, message revision, SDK version, and entry point. They do not need consent-form text, advertising identifiers, user-generated data, or a raw consent record.

Start with one controlled mismatch

Add a test account or test device whose operating-system language is English and whose in-app language is French. Route consent presentation through one locale adapter, publish the French provider message, and verify the first form plus the privacy-options form. Then switch back to English without clearing consent. The visible language should change, the stable purpose choices should not, and any re-consent request should be explainable by a policy revision rather than by the locale switch.

Consent text also needs a versioned record of what each user saw; see how to version localized legal copy with a consent audit history.