Localization
Localization lets a single bot scenario reply to users in different languages. Instead of building a separate scenario or duplicating text for every language, you set up translation variables once and use them in messages, captions, and buttons — the bot automatically outputs the right translation depending on each user's language.
What this is useful for
- International bots — one scenario serving an audience from multiple countries.
- Stores or services with multilingual customers — product cards, notifications, buttons in the customer's language.
- Supporting several languages within one country — for example, English and Spanish, or English and French.
- Quickly localizing an existing bot — no need to rebuild the scenario; just add translations and swap texts for variables.
How it works
- You create a translation dictionary at the bot level — it's shared across every scenario (flow) of that bot.
- In the dictionary, add the languages you need and mark one of them as the default language.
- Create localization variables — short names (e.g.
name,btn_buy,welcome_text) — and enter a translation for each language. - In any text field of the builder (message text, media caption, button text, URL, etc.), insert a variable like this:
{{trans.name}}
- When the bot sends a message to a specific user, it substitutes
{{trans.name}}with the translation for that user's language.
The "Localization" tab
The translation dictionary is managed from the builder's unified settings window: open the "More" dropdown in the builder header and select "Localization".
Languages
- Add languages with the "+ Add language" button — the list is pulled from the same shared catalog used in the widget settings.
- The star next to a language marks it as the default language. Click the star on another language to make it the default instead.
- Remove a language with the button next to its name — this deletes all translations for that language (the variables themselves stay).
Variables and translations
The list of variables is shared across all languages — you create a variable once, then fill in its translation separately on each language tab:
- "+ Add translation" creates a new variable. Give it a short name (letters, digits,
_and-— case doesn't matter, it's automatically lowercased). - Switch between language tabs to fill in the translation for each language. The translation field is multi-line; hovering over it reveals an expand button in the corner that opens a full editor with a formatting preview, just like in text blocks.
- The trash icon deletes the variable for all languages at once.
- Translation values can contain regular variables and Markdown formatting — they're resolved as usual.
Automatic translation via AI
To avoid translating every variable by hand:
- On the default language tab, the "Translate for all languages (N)" button appears, where N is the number of empty translations across the other languages. Clicking it has the AI translate every missing value for every language, based on the default-language text.
- On any other language tab, the "Translate empty" button translates only the missing values for that language.
While translating, the button shows progress (e.g. "Translating: RU (1/3)…") and can't be clicked again until it finishes. Translations you already entered by hand are never overwritten — only empty fields get translated.
Translation uses the same AI assistant and the same daily request limit as the "Translate message" feature in the Chats section. If the limit runs out partway through translating several languages, the translations already received are kept and you'll see a notification that the process finished partially.
Import and export
- "Export" saves the entire translation dictionary to a file.
- "Import" loads a file back in: new variables are added, and existing variables' values are updated (no duplicates are created).
Handy for moving translations between bots or handing texts off to a professional translator outside the builder.
Inserting a translation variable into text
There are two ways to add {{trans.*}} to a field:
From the variable list
In any text field, start typing {{ — a list of available variables appears. Localization variables are grouped separately under "Localization" and show the default-language translation as a hint.
Right from the field — the "Localization" button
Next to text fields (alongside the emoji and variable-insert buttons) there's a "Localization" button. It opens a small form right under the field:
- If no languages have been added yet, the form shows an "Add languages" link that opens the Localization tab.
- If the field already contains
{{trans.name}}, the form automatically loads the existing translations for editing. - Enter the variable name and translations for each language, optionally click "Translate" (translates from the default language into the others), then "Save" — the variable is created or updated, and the
{{trans.name}}macro is inserted into the field.
This lets you create and edit translations without leaving the block's settings.
How the bot picks the right translation
For every {{trans.name}} variable, a three-step rule applies:
- Look up the translation for the current user's language.
- If there's no translation for their language, or it's empty, use the translation for the default language.
- If that's empty too, the variable outputs as an empty string.
This means the bot never "breaks" because of a missing translation — at worst it simply won't show that piece of text. That's why the default language is the one worth filling in first, and completely.
Letting users pick their own language
A user's Telegram client language doesn't always match the language they want to talk to the bot in. To let them choose:
- Add buttons with language names to your scenario (e.g. in the welcome command), such as:
- "🇬🇧 English"
- "🇷🇺 Русский"
- Route each button to a separate command containing a "Database" block → source "User" → action "Change Language" — set the language code (
en,ru, etc.) matching the button that was pressed. See the Database section for details on that block. - Once the language is saved, every
{{trans.*}}variable in the scenario automatically starts showing the language the user picked — starting with the next message and for every message after that, with no further action needed.
The same principle applies to web-widget guests — the language is tracked independently per user there too.
Where else the user's language is applied
- On the builder canvas, texts and button captions containing
{{trans.*}}show the default-language translation — this is just a preview; real users still see their own language. - In the conversation history (Chats section) — if a user tapped a button that used a translation variable, the conversation list and the message thread show that button's text in the user's own language, not the raw macro.
Example
A variable named greeting is set up like this:
| Language | Value |
|---|---|
| English (default) | Welcome, {{user.first_name}}! |
| Русский | Добро пожаловать, {{user.first_name}}! |
Message text in the block:
{{trans.greeting}}
A user whose language is en receives "Welcome, John!", a user with ru receives "Добро пожаловать, Иван!", and a user with any other language (say, de) receives the default-language translation — the English text.
Tips
- Name variables after their meaning, not where they're used:
btn_buy,welcome_text,order_confirmed— this keeps the growing list easy to navigate. - Always fill in the default language completely — it's the safety net for any language missing a translation.
- Translation variables can be used anywhere: message text, media captions, button text and URLs, auto-message text.
- Inside a translation value you can freely use other bot variables (
{{user.first_name}},{{balance}}, etc.) — they're substituted as usual. - Review AI-translated text before relying on it — the AI is generally accurate, but for important copy (names, legal wording) a manual check is worth the extra step.
