Build a multilingual site in Bubble using Option Sets or a translations data type to store text in multiple languages, a language switcher UI, and user language preferences. This tutorial covers static text translation, dynamic content translation, and persisting language selection across sessions.
Overview: Multilingual Sites in Bubble
A multilingual site serves content in multiple languages based on user preference. Bubble does not have built-in i18n, but you can implement translations using Option Sets for static text and database records for dynamic content. This tutorial covers both approaches.
Prerequisites
- A Bubble account with an app
- Translations ready for your target languages
- Basic understanding of Option Sets and conditional expressions
Step-by-step guide
Create a Language Option Set
Create a Language Option Set
Go to Data → Option sets → Create 'Language' with options: en (English), es (Spanish), fr (French), etc. Add a 'label' attribute for display names. On the User data type, add a 'preferred_language' field (type: Language option set, default: en).
Expected result: Language options and user preference field are ready.
Store static translations in Option Sets
Store static translations in Option Sets
Create a 'Translation' Option Set. Each option represents a text key (e.g., nav_home, nav_about, btn_signup). Add attributes for each language: text_en (text), text_es (text), text_fr (text). Enter translated values for each key. This approach is fast (zero WU) since Option Sets are cached.
Pro tip: For apps with many translations, use a Translation data type instead of an Option Set for easier management.
Expected result: Static text translations stored in an Option Set with one attribute per language.
Build the language switcher
Build the language switcher
Add a Dropdown in your header with data source: All Languages. Display the label attribute. When the user changes the selection: Make changes to Current User → preferred_language = Dropdown's value. If the user is not logged in, use a custom state or URL parameter to store the selection.
Expected result: Users can switch languages from a dropdown in the header.
Display translated text throughout the app
Display translated text throughout the app
For every static text element, replace hardcoded text with a dynamic expression. Example: Get option Translation where Display = nav_home, then use a conditional: When language is en → text_en, When language is es → text_es. A cleaner approach: create a utility expression using the :formatted as text operator to select the right attribute based on the language code.
Expected result: All static text displays in the user's selected language.
Translate dynamic database content
Translate dynamic database content
For database content (articles, products), add translation fields directly on the Data Type: title_en, title_es, description_en, description_es. Display using conditionals based on the user's language. Alternatively, create a separate Translation data type linking content ID to language code and translated text for more scalable management.
Expected result: Dynamic content displays in the user's selected language.
Complete working example
1MULTILINGUAL SITE — ARCHITECTURE2==================================34LANGUAGE OPTION SET:5 en (English), es (Spanish), fr (French)67STATIC TEXT (Option Set approach):8 Translation Option Set:9 nav_home: text_en="Home", text_es="Inicio", text_fr="Accueil"10 btn_signup: text_en="Sign Up", text_es="Registrarse", text_fr="S'inscrire"1112DYNAMIC CONTENT (database approach):13 Article type: title_en, title_es, description_en, description_es14 OR ContentTranslation type: content_id, language, field_name, value1516LANGUAGE DETECTION:17 1. User's preferred_language (if logged in)18 2. URL parameter ?lang=es (for sharing)19 3. Default: en2021DISPLAY LOGIC:22 Text element content:23 When language is en → Translation's text_en24 When language is es → Translation's text_es25 When language is fr → Translation's text_frCommon mistakes when building a multilingual site in Bubble
Why it's a problem: Hardcoding text in elements instead of using translations
How to avoid: Replace all static text with dynamic expressions referencing the Translation Option Set
Why it's a problem: Adding too many languages to an Option Set
How to avoid: For more than 3-4 languages, use a database Translation data type instead of Option Set attributes
Why it's a problem: Not persisting language selection for logged-out users
How to avoid: Use a URL parameter (?lang=es) or browser localStorage via JavaScript to persist the selection
Best practices
- Use Option Sets for static text in apps with 2-3 languages for zero-WU performance
- Use a database Translation type for apps with many languages or dynamic content
- Persist language preference on the User record for logged-in users
- Use URL parameters for language sharing and SEO
- Test all pages in every supported language before launching
- Provide a visible language switcher in the header on every page
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to make my Bubble.io app multilingual with English and Spanish. I need a language switcher, translated static text, and translated database content. What is the best approach?
Add multilingual support for English and Spanish. Create a Translation Option Set for static text, add a language switcher dropdown, and display all text based on the user's language preference.
Frequently asked questions
Does Bubble have built-in translation?
Bubble has a Languages section in Settings that supports basic text translation, but it is limited. Most builders use Option Sets or database records for more control.
Can I auto-detect the user's browser language?
Yes. Use a JavaScript snippet in an HTML element to read navigator.language and set the default language accordingly.
How do I handle right-to-left languages like Arabic?
Add dir='rtl' via a conditional on the page's HTML element. Also adjust text alignment and layout direction for RTL languages.
Will multiple languages affect SEO?
For best SEO, use URL parameters (?lang=es) or separate page slugs (/es/about) so search engines can index each language version.
Can I translate Bubble system messages?
Yes. Go to Settings → Languages tab to translate built-in messages like error texts and email templates.
Can RapidDev build a multilingual Bubble app?
Yes. RapidDev implements multilingual solutions with translation management, RTL support, and SEO-optimized language routing.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation