App texts, short for Application texts and messages, are a kind of database for the text strings you use around your app. You can use them for a single language, or translate every string into other languages to offer users a multilingual app.
App texts are part of Bubble's static data features. That means they aren't dynamic like the database, and your app has to be redeployed whenever one changes. Because of that, they're meant for shorter content like headers, menu options, and button labels, not long strings like articles or product descriptions.
What is localization?
What is localization?
Localization is the process of adapting an app so it works naturally for people in different languages and regions. Translating your text strings is the core of it, which is exactly what app texts let you do. You'll see the term used widely outside Bubble, sometimes shortened to "l10n," so it's worth knowing if you're planning to support more than one language.
App texts become part of your app's codebase and are downloaded to every user on page load. Never use them to store sensitive information.
Using app texts
An app text can be used in any expression, so you can assign it to any element property that accepts a dynamic text. This includes text elements, button and checkbox labels, text input fields, tooltips, and many other places.
In this example, we have a static text string (My dashboard) connected to an app text of the same name. This lets you maintain app-wide strings in one place and translate them into other languages.
In the editor, the property shows App text ([name]), while your running app shows the string you saved for the currently active language.
To use an app text as the Text property of a text element, search for the data source App text.
This also means you can use app texts in workflows, element conditions, and anywhere else you can insert a dynamic expression. In the example above, we selected App text as the data source and My input as the operator. My input is the ID of the specific string we want to show, which means it has to be created first.
Editing app texts
To open the app text editor, go to the Settings tab, in the Languages section. Under General settings you'll find your app's default language and the field on the user that determines their language preference (more on that below).
Under Application texts and messages, you'll find every custom string you've added, along with Bubble's core texts. The left column is the string's ID. In the earlier example, the ID was My input.
The app text editor, in the Languages section of the Settings tab. Custom texts like My Dashboard appear alongside Bubble's core texts, each with an editable string on the right.
Open the Settings tab. In the left menu, click the Settings tab.
Go to the Languages section. Select the Languages section. Under General settings, you'll find your app's primary language and the language field on the user type. Under Application texts and messages, you'll find your text strings.
Find and edit your text. Locate the text you want to edit by its ID in the left column, such as My Dashboard, then edit the string shown in the field on the right. Use the Currently editing messages and texts for dropdown to switch which language you're editing.
Core texts
Core texts are the strings Bubble includes by default. You can change what they say, but you can't delete them, and their IDs stay fixed. They cover the error and informational messages tied to Bubble's core functionality, and they're already translated into every available language.
Bubble's core texts are the built-in messages tied to core functionality, each with an ID like BAD_CSV. You can't delete them or change their IDs, but you can edit the string shown on the right to reword the message or translate it.
Element strings
Some elements and plugins add their own strings, which appear at the bottom of the list. The multi-file uploader plugin, for example, adds strings like Cancel upload and Remove file.
Exporting and importing translations
Bubble lets you export your language strings to a CSV file, adjust them, and re-import the file. This is an efficient way to have someone translate your strings without giving them access to the Bubble editor.
Exporting
Open the export dialog. Click Export. Bubble asks which languages to include.
Select the languages. Every language is selected by default. Use Select All to toggle them all at once, or check individual languages to export only the ones you need.
Download the file. Click Export in the dialog to download the CSV.
What the CSV looks like
The exported file has one row per text string and one column per language. The first few columns identify each string:
Column | What it holds |
| Where the string comes from, such as CORE for Bubble's core texts or USER_TEXTS for your own. |
| An internal identifier for the string. |
| The string's ID, like My Dashboard or |
After those, each remaining column is one language, headed by its language code (af_za, sq, and so on). The cell where a string's row meets a language's column holds that string's translation in that language. To translate your app, fill in the cells under each language column.
Don't change the text IDs or the column structure. Bubble matches each row back to its string using these, so altering them will break the import. Importing also overwrites all strings, even where a cell is left empty, so keep any string you want to retain in the file.
Importing
Open the import dialog. Click Import.
Choose your file and delimiter. Set the Data delimiter to match your file (a comma is the default), then click Pick a file to upload and select your CSV.
Validate the data. Click Validate data. Bubble checks the file and confirms how many elements are ready to upload.
Upload the data. Once validation succeeds, click Upload data to import your translations.
Importing a CSV overwrites all strings, even where a cell is left empty. To keep a string as it was on export, make sure it stays in the file.
How Bubble determines the language
On web apps, Bubble picks the current language using this order of priority:
The lang parameter in the URL, if set
The current user's language, if the field exists and its value is valid
The app's primary language
English
Setting up multiple languages
App texts use IETF language tags to identify each language and dialect.
Setting the main language
The main language is what Bubble uses to run your app when no language setting applies. It defines the messages your app can send and show, and it changes how location-sensitive elements behave, for example how dates are formatted in the date input, calendar, and map elements.
Setting the language field on the user
Users don't have a built-in language field, but Bubble lets you add one if you need it. Bubble reads the user's language from this field, so its value has to be a valid IETF language tag, one of the codes in the language dropdown.
The method below uses an option set, which gives your users a clean list of languages to choose from while storing the correct code behind each one. This is just one suggested approach. Any field that returns a valid IETF language tag will work, so you can set this up however suits your app.
Create a Languages option set. Create an option set to hold your languages, and give it an attribute for the language code. In this example, the Languages option set has an IETF language tag attribute, and the Spanish option stores the code
es_es. Add an option for each language you want to support.Add the field to the User. On the User data type, create a field whose type is your Languages option set. Here it's a field called Language. The field's name doesn't matter, only that it holds a language with a valid code.
Configure the language settings. Go to the Settings tab, in the Languages section. Set Language field on the user type to the field you created. Since this field holds an option set rather than a plain text code, also set Attribute for language field to the attribute that holds the code, in this example IETF language tag. Bubble then displays strings in each user's language based on that value.
If the field is empty, Bubble falls back to the language set in Application primary language.
Setting the language with a URL parameter
You can also set the language in the URL with the lang query parameter: add lang=code to the URL, where code is the language code from the Settings tab, in the Languages section. Most, but not all, of these codes follow a two-character, underscore, two-character format.
For example, to run your app in Russian, you'd use https://myapp.com?lang=ru_ru.
App texts in native mobile apps
App texts work in native mobile apps too, so you can localize your content there as well. The main difference is how the app decides which language to show.
On web, Bubble determines the language from a language field on the User data type (as described above). On mobile, it works differently: the app uses the primary language set on the user's device instead.
How it works
When a mobile app launches, Bubble compares the device's primary language against the list of supported languages in your app's mobile settings. If it finds a match, it uses that language's app text translations. If not, it shows content in the primary app language.
You manage supported languages in the Settings tab, under Supported languages.
Supported languages and dialects
Some languages have regional variations, known as dialects. Spanish, for example:
es_es (Spanish, Spain)
es_mx (Spanish, Mexico)
es_ar (Spanish, Argentina)
Bubble lets you set a specific dialect for each supported language, using the Select base language and Select region or dialect fields. A user's device, though, might report only a base language like es, with no region. To handle that, each supported language has a Select fallback language setting that decides which dialect to use when the device gives only the base language.
For example, if you support es_mx and es_ar and a device reports only es, Bubble uses the fallback dialect you set, such as es_mx.
How mobile chooses a language, in short
Device reports | What the app shows |
A supported dialect | That dialect's translation |
A base language only | The fallback dialect you defined |
No match | The app's primary language |
Updating supported languages
Adding a supported language can go out in an over-the-air (OTA) update.
Translations for system-level prompts, like permission messages, need a new build, since those values are compiled into the native binary.
FAQ: App texts
What does Bubble show if a string isn't translated into the active language?
What does Bubble show if a string isn't translated into the active language?
It displays (no translation) in place of the string. Bubble's error console, in the bottom-right of the debugger, also flags a warning when you preview the page.
What happens if the user's language field is empty?
What happens if the user's language field is empty?
If the field is empty or returns an invalid language code, Bubble falls back to the language set in Application primary language.
How do app texts affect performance?
How do app texts affect performance?
Your app texts become part of your app's JavaScript source files, so they're downloaded to every user who opens a page. For performance, Bubble only downloads the text in the language the user has selected, which is why changing the language requires a page load: a new JavaScript file has to be generated and downloaded.
App texts are no more taxing than putting the string directly on an element, and if a string is used in several places, they're lighter, since it's only stored once. Even if you don't plan to translate your app, keeping all your strings in one place can be useful.
Do app texts support right-to-left (RTL) writing?
Do app texts support right-to-left (RTL) writing?
Yes. App texts support RTL languages like Arabic, Hebrew, and Urdu. You may need to adjust your design when switching between LTR and RTL languages, so we recommend testing your app in both.
Known issue: right-to-left (RTL)
When text is displayed in RTL and you apply certain operations or changes, it may switch back to a left-to-right display. If RTL support is a priority, preview your pages in run mode to confirm they display correctly.
I changed an app text, so why isn't it showing in my live app?
I changed an app text, so why isn't it showing in my live app?
A few things to check:
Changes appear in Development after you refresh the page, and in Live after you deploy and refresh.
Confirm you're viewing the app in the same language as the string you changed.
Confirm the Saving indicator next to the edit menu reads Saved, so you know the change synced to Bubble's server. If it doesn't, check your internet connection.
Footnotes
IETF language tag: a widely used standard for identifying languages on the internet. It combines standards like ISO 639 to distinguish language variants, such as British English (en_gb) and American English (en_us). IETF (the Internet Engineering Task Force) is an organization that develops voluntary standards for the internet.
Primary device language: the top language set in the user's device settings. This is the language the operating system uses for menus, apps, and system messages.
Over-the-air (OTA) update: an update pushed to users without a new build or app store approval. Changes take effect the next time the app is opened.
Compiled into the native binary: this text is included directly in the app's packaged code, so it can't be changed without creating a new build and resubmitting to the app stores.








