Many Odoo implementations serve users or customers across more than one language. A French sales team, a German warehouse, a Spanish customer portal. For all of this to work seamlessly, Odoo needs a way to store field values in multiple languages at once. That is exactly what translated fields do.
A translated field holds one value per language. When a French user opens a product record, they see the French product name. When a German user opens the same record, they see the German name. One record in the database, multiple representations depending on who is looking.
This guide explains how translated fields work in the Odoo ORM, how to create and manage them, and the practical situations where they make a real difference in how your business operates.
What Is a Translated Field in Odoo
A translated field is a text-based field in the Odoo data model that can store a different value for each active language in the system. The translation is transparent to the user: they always see the value in their own language without needing to do anything special.
In terms of Odoo field types, translation is supported on:
- Char: short single-line text (product names, category labels, job titles)
- Text: longer multi-line text (descriptions, notes)
- Html: rich text with HTML markup (website content, email template bodies)
Numeric fields, date fields, Many2one fields, and boolean fields cannot be translated. Translation only applies to fields that carry human-readable text.
How It Looks in the Interface
When a translated field is active in Odoo, a small language flag icon appears next to the field in edit mode. Clicking it opens a dialog that shows the value for each installed language, letting authorized users manage all translations from one place.
In read mode, the user simply sees the value in their own language. If no translation has been set for their language yet, Odoo falls back to the base language value (usually English) rather than showing an empty field.
How the Translated Field Works
Understanding the internals of translated fields helps you make better decisions about when to use them and how to manage them at scale.
The translate=True Parameter
In the Odoo ORM, you enable translation on a field by adding translate=True to the field definition. Here is a simple example on a custom Char field:
from odoo import models, fields
class ProductTemplate(models.Model):
_inherit = 'product.template'
x_marketing_tagline = fields.Char(
string='Marketing Tagline',
translate=True
)
With this single parameter, Odoo knows to store and retrieve different values for this field depending on the active language context. This is one of the most elegant features in the Odoo framework.
Where Translations Are Stored
The storage mechanism has changed across Odoo versions:
- Odoo 15 and earlier: Translations were stored in a separate
ir.translationtable. Every translated value was a row in that table, linked to the model, field name, record ID, and language code. - Odoo 16 and later: Translations are stored directly in the model's own database table as a JSONB column. For example, a
namefield withtranslate=Trueis stored as a JSON object like{"en_US": "Laptop Stand", "fr_FR": "Support pour ordinateur portable", "de_DE": "Laptopständer"}.
The move to JSONB in Odoo 16 was a significant improvement. It eliminates expensive joins with the translation table and makes querying much faster, especially on models with many records.
How Language Context Works
When Odoo reads a translated field, it checks the active language in the context. If you are logged in as a French user, the ORM automatically fetches the French value. If you make an API call, you control the language by passing it in the context:
models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'product.template', 'read',
[[product_id]],
{'fields': ['name'], 'context': {'lang': 'fr_FR'}}
)
This is important when building integrations or export scripts. Always pass the correct language in the context to get the right translated value.
The translate Parameter with a Callable
The translate parameter also accepts a callable for advanced use cases. The most common example is using translate=_ to mark static string values (like selection labels) for translation via the standard Odoo translation export mechanism. This is distinct from record-level field translations and is mainly used in Odoo development for translating module strings.
Fallback Behavior
If a translation has not been set for the active language, Odoo does not return an empty value. It falls back to the base language of the database (typically English). This graceful fallback means your users always see something meaningful, even in partially translated environments.
Business Use Cases
Translated fields are not just a technical feature. They solve real problems that come up in businesses operating across languages. Here are five common scenarios.
1. E-commerce: Multilingual Product Names and Descriptions
If you sell through the Odoo website or shop, your customers expect to browse in their own language. The name and description fields on product.template are translatable by default. This means you can maintain a single product catalog and provide localized names, sales pitches, and technical specifications without duplicating records.
A customer visiting your French website sees French product names and French descriptions. The underlying product is the same, stock levels are the same, pricing rules are the same. Only the displayed text changes.
2. Email Templates in Multilingual Companies
Odoo's email templates use translated Html fields for their body content. When you send an order confirmation to a German customer, Odoo automatically uses the German version of the template body if one has been set. This works because the template fields have translate=True.
For companies with customers across multiple countries, this means a single template can serve all markets cleanly without conditional logic or separate template records per language.
3. Website Pages and Blog Content
Odoo website pages use translatable Html fields for their content. When your website has multiple languages activated, editors can maintain different text for each language version of the same page. This is how multilingual Odoo websites work natively, without any third-party plugin.
From an SEO perspective, this also means each language version of the page can have its own meta title and meta description, helping you rank in local search results across different markets.
4. Selection Field Labels for International Teams
When you define a Selection field in Odoo Python code, the option labels can be marked for translation using the standard _ translation function. This means a dropdown that shows "In Progress", "On Hold", and "Completed" to an English user will show the properly translated equivalents to users in other languages.
This is especially useful in HR, project management, and any workflow where teams across different offices need to work with the same records but in their own language.
5. Custom Fields in Multilingual Reporting
If you have created custom fields using Odoo customization or Odoo Studio fields for internal categorization (service categories, risk levels, product segments), making those fields translatable ensures that reports and dashboards display correctly for all users, regardless of their language setting.
Without translation on these fields, a French user might see English labels in their reports, which creates confusion and reduces adoption.
Creating or Customizing Translated Fields
There are a few ways to create or enable translation on a field in Odoo, depending on whether you are working in a no-code environment or directly in Python.
Using Python (Recommended for Developers)
The cleanest way to create a translated field in the Odoo ORM is to define it in a Python model with translate=True. This is the standard approach in any Odoo developer guide or Odoo technical tutorial:
from odoo import models, fields
class ProductTemplate(models.Model):
_inherit = 'product.template'
x_product_highlight = fields.Char(
string='Product Highlight',
translate=True
)
x_product_note = fields.Html(
string='Product Note',
translate=True
)
Adding translate=True is all it takes. From that point, Odoo handles everything: the language flag in the UI, the translation storage, the fallback logic.
Using Odoo Studio Fields
Odoo Studio does not expose the translate option in its field configuration panel. When you create a Char or Text field in Studio, it is not translatable by default.
However, you can enable translation on a Studio field via the XML-RPC API after it has been created. Find the field's ID in ir.model.fields and update its translate property:
# Find the Studio field
field = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'search_read',
[[[('name', '=', 'x_my_field'), ('model', '=', 'product.template')]]],
{'fields': ['id', 'name', 'translate']}
)[0]
# Enable translation
models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'write',
[[field['id']], {'translate': True}]
)
This approach works well for teams doing Odoo customization through scripts or notebooks without access to source code.
Managing Translations: Export and Import
Once translated fields are in place, the translation workflow in Odoo is straightforward:
- Go to Settings > Translations > Export Translation to download a .po or .csv file with all untranslated strings for a given language.
- Fill in the translations in the file (or send it to a translator).
- Go to Settings > Translations > Import Translation to upload the completed file back into Odoo.
For record-level translations (like product names), you can also edit them directly in the interface using the language flag icon next to the field. This is more practical for small volumes of content.
Translating via the API
When writing or updating a translated field via the XML-RPC API, pass the language in the context:
# Write the French translation for a product name
models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'product.template', 'write',
[[product_id], {'name': 'Ordinateur Portable Ultra'}],
{'context': {'lang': 'fr_FR'}}
)
Writing with a specific language in the context only updates that language's translation. Other language values remain untouched. This is the clean way to push translated content into Odoo from an external system.
Best Practices
Translated fields are straightforward when used correctly, but a few habits will save you a lot of time and confusion.
Always Set the Base Language Value First
Before adding translations for other languages, make sure the base language value is correct and complete. All other translations are derived from this base. If you change the base value later, the other translations do not update automatically and will be out of sync.
Only Translate Fields That Actually Need It
Not every text field needs to be translatable. Internal reference codes, technical identifiers, and fields only visible to back-office staff in a single-language company do not benefit from translation. Adding translate=True to too many fields increases complexity and the volume of translations that need to be maintained.
Use the Export/Import Workflow for Large Translation Jobs
For large catalogs (hundreds or thousands of products), editing translations one by one in the interface is impractical. Use the translation export feature to generate a file, translate in bulk, and import back. This is much faster and less error-prone.
Pass the Language Context in All API Calls
When reading or writing translated fields via the Odoo API, always pass 'lang': 'xx_XX' in the context. Without it, the API defaults to the user's language, which may not be what you intend. Being explicit avoids subtle bugs where data ends up stored under the wrong language.
Maintain Translations When the Source Changes
When you update the base language value of a translated field, the other language translations are not automatically updated. Build a review process into your content workflow so that translators are notified when the source content changes and translations need to be updated.
Common Pitfalls
Even experienced Odoo consultants run into these mistakes. Being aware of them upfront will save you a lot of debugging time.
Forgetting to Pass the Language Context in API Writes
This is the most common mistake when integrating external systems with Odoo. If you write a product name via the API without specifying a language, Odoo writes it in the user's default language. If that user happens to be configured in English, but you wanted to set the French translation, you have overwritten the English value instead. Always be explicit about the language context.
Assuming Translated Fields Are Filtered in Searches
When you search on a translated field (for example, searching for a product by name), Odoo searches in the active language by default. A product named "Laptop Stand" in English will not appear in search results if the user is in French and the French translation has not been set yet. Make sure translations are in place before expecting searches to work across languages.
Mixing Translated and Non-Translated Fields in Reports
If a custom Odoo report or export uses a mix of translated and non-translated text fields, the output may be inconsistent: some labels appear in the user's language, others always appear in the base language. Review your report fields carefully and decide upfront whether each one should be translatable.
Not Accounting for Translation Overhead in Computed Fields
If you have an Odoo computed field that builds a string from multiple translated fields, the computation runs in the active language at the time of the request. The result is not automatically stored per language. If you need a computed concatenation of translated values in multiple languages, you need to handle the language-specific computation explicitly.
Removing a Language Without Cleaning Up Translations
When you deactivate or remove a language in Odoo, the translation values for that language may remain in the database depending on your version. This is usually harmless, but it can add clutter. Always check your translation data after deactivating a language in a production environment.
Conclusion
Translated fields are one of the most practical features in the Odoo framework for companies working across multiple languages. A single parameter, translate=True, unlocks the ability to maintain localized content for product catalogs, email templates, website pages, and custom fields without duplicating records or managing separate systems.
The key is to be deliberate about which fields actually need translation. Use it where it makes a difference for your users or customers, manage translations through the export/import workflow for scale, and always be explicit about the language context when working with the Odoo API.
Whether you are setting up a multilingual e-commerce store, rolling out Odoo to international teams, or doing Odoo development on a custom module, understanding translated fields will help you build cleaner, more user-friendly solutions.
Working on a multilingual Odoo implementation and need guidance on field configuration or translation workflows? Reach out to the Dasolo team and we will be happy to help you get it right.