Odoo has built-in internationalization support for both server-side Python code and client-side JavaScript. This guide covers how to mark strings for translation in your module, export the translation template, create language files, and follow best practices for robust i18n.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/odoo/documentation/llms.txt
Use this file to discover all available pages before exploring further.
How Odoo Translates Content
Odoo automatically extracts translatable strings from XML view definitions. For imperative code (Python functions, JavaScript), you must explicitly mark strings for translation using wrapper functions. Translations are stored in.po files inside <module>/i18n/ and are loaded automatically when the corresponding language is installed.
Implicit Exports (Automatic)
Odoo automatically marks the following content as translatable without any code changes:- XML views (non-QWeb): All text nodes and the
string,help,sum,confirm,placeholderattributes. - QWeb templates (server and client): All text nodes outside
t-translation="off"blocks;title,alt,label, andplaceholderattributes. - Model fields (when the model has
_translate = True, which is the default):stringandhelpattributesselectionvalues (when defined as a list or tuple)- Field values where
translate=Trueis set
Explicit Exports (Python)
For strings in Python code, wrap them with the translation function:Lazy Translation in Python
UseLazyTranslate for module-level constants or class attributes — the lookup is deferred until the string is actually rendered:
Explicit Exports (JavaScript)
In JavaScript, import and use_t from the OWL environment or from web.core:
Lazy Translation in JavaScript
Use_lt for strings initialized at file-read time (e.g., static maps):
Exposing Translations to the Frontend
Module translations are not exposed to JavaScript by default. To make them available, either:- Name your module with a
website_prefix (e.g.,website_sale,website_event) — these are automatically exposed. - Register explicitly by overriding
_get_translation_frontend_modules_nameonir.http:
Common Pitfalls
Variables — Don’t Interpolate Before Translating
- ❌ Wrong
- ✅ Correct
Blocks — Keep Sentences Together
- ❌ Wrong
- ✅ Correct
Plurals — Account for All Languages
- ❌ Wrong
- ✅ Correct
Read vs. Run Time — Don’t Translate at Import Time
- ❌ Wrong
- ✅ Correct
Exporting the Translation Template
Export all translatable strings from your module as a.pot file (PO Template):
Open the export dialog
Log in to the Odoo backend and navigate to Settings → Translations → Import / Export → Export Translations.
Select your module and format
- Language: leave empty (new language/empty template)
- Format: PO File
- Module: your module name
Creating Language Files
From the.pot template, create per-language .po files:
- Using msginit
- Using POEdit
- Manual copy
.po files in <yourmodule>/i18n/:
Translations for all loaded languages are reinstalled/updated whenever you install or update the module.
Translation Context and Variables
When usingodoo.tools.translate._, the language and module are resolved by inspecting the caller’s local variables for self.env or a context dict. This works inside model methods but not inside regular functions or comprehensions. Use Environment._() for more reliable context: