Localization
Translate a flow and send each user their own language.
#What localization does
Localization lets one flow speak every language your users do. You write your notifications once in a default language, add the languages you want to support, and provide a translation of each message. At send time Pushlane picks the language that matches the recipient's device and delivers that copy — automatically, per user. You do not build a separate flow per language.
Only the notification title and body are localized. Image, deeplink, and the other message fields are shared across every language.
#The Localization table
Open a flow in the builder and open the Localization panel from the left rail. It shows a table:
- Rows — every message in the flow, split into its title and body (one pair per message variant), in the same order as the flow outline.
- Columns — one per language. A new flow starts with a single column: your default language. Add language adds a column to fill in; you can pick from a suggested list or type any locale code.
The default-language column edits the very same title and body you see in the message inspector — it is the one source of truth for that copy. The extra columns hold the translations. Editing a cell here is the same as editing anywhere else in the builder: it is undoable, works in real-time collaboration, and is saved with the flow.
#Auto-translate
Filling every language by hand is optional. The Auto-translate button at the top of the Localization panel translates your default-language copy into all of your target languages at once, powered by Claude. It is written for push — natural, native-sounding copy at notification length, not a word-for-word machine translation.
- Auto-translate is available on paid plans (Growth and up). On the free plan the button prompts you to upgrade. See Billing & usage for plans.
- It spends AI credits from your monthly allowance. The exact cost is shown in Settings → AI credits.
- By default it only fills the empty cells, leaving copy you have already written untouched. A Retranslate all option overwrites every cell.
{{ first_name | friend }} are copied into every translation verbatim, so variables keep working in every language. If a translation would drop or mangle a token, Pushlane rejects that cell rather than ship broken personalisation — it stays empty and the missing-translation error points you to it.#How the language is chosen at send time
Every event a device sends carries its locale — for example fr_FR — in the event context. Pushlane records it as the user attribute locale. When a localized flow reaches a message, the engine resolves the language from that attribute in three steps:
| Step | Rule | Result |
|---|---|---|
| 1 — Exact | The device locale matches a declared language exactly (fr-FR = fr-FR). | That language's copy. |
| 2 — Language | The language matches even when the region differs (fr-CA → fr, or fr-FR). | That language's copy. |
| 3 — Default | No declared language matches the device. | The default-language copy. |
device locale "fr_FR" → French (exact / language match)
device locale "fr-CA" → French (language match, region ignored)
device locale "de_DE" → English (no match → default language)
no locale on the user → English (default language)#Where the locale comes from
You do not set the locale yourself. Every Pushlane SDK and drop-in reads the device's current locale and sends it in context.locale on each event. Pushlane normalises it (en_FR → en-FR) and stores the most recent value as the locale user attribute — no extra SDK call required.
locale at a time: the most recent one their device reported. This mirrors how personalisation variables are resolved from stored attributes.locale is a reserved system attribute name. You can set it yourself — Pushlane.setAttributes({ locale: 'fr-CA' }) is the supported way to honour an in-app language picker that differs from the OS language. Re-apply it on each app launch: the device projection also writes locale at launch and the most recent write wins, so a one-time override would be reverted by the next session. The value must be a BCP 47 tag (fr, fr-CA, pt-BR…). A non-locale value can't drive language selection: that user falls back to the default language until the device reports a locale again. Never reuse locale (or app_version, os_version, install_env) for unrelated custom data — the device projection and your writes share one value, most recent wins.Related: Notification templates · How Pushlane works