From odoo-dev-toolkit
Add multi-language (i18n) support to Odoo 18 modules — PO files, JSONB translations, JS _t(), email templates, and website language configuration. Use this skill when the user wants to translate an Odoo module, add language support, create PO files, internationalize JS code, or make email templates multilingual. Trigger on: "translate", "i18n", "translation", "PO file", "language", "multilingual", "překlad", "přeložit", "jazykové mutace", "vícejazyčný", "lokalizace", "internationalization", "_t()", "multi-language".
How this skill is triggered — by the user, by Claude, or both
Slash command
/odoo-dev-toolkit:odoo-i18nThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Add complete multi-language support to Odoo 18 modules. This covers Python model strings, QWeb templates, JavaScript UI, email templates, and website language configuration.
Add complete multi-language support to Odoo 18 modules. This covers Python model strings, QWeb templates, JavaScript UI, email templates, and website language configuration.
Read references/i18n-patterns.md for exact patterns, PO file format, and examples before writing any translation code.
Odoo 18 removed the ir_translation table. All translatable fields are stored as JSONB columns with language keys:
{"en_US": "Hello", "cs_CZ": "Ahoj", "uk_UA": "Привіт"}
This applies to ALL fields with translate=True: name, description, body_html, arch_db, etc.
Even if your primary content is in another language (e.g., Czech), the JSONB key for the source text is en_US. PO files translate FROM the source (English) TO the target language.
Odoo 18's PO parser requires :line_number suffix on code: references. Without it, you get ValueError: invalid literal for int().
# CORRECT:
#: code:addons/my_module/static/src/js/main.js:0
# WRONG (will crash):
#: code:addons/my_module/static/src/js/main.js
Use :0 when the exact line number is unknown.
_('string') in selection labels, field strings, error messages<template> elements (auto-extracted)_t('string') from @web/core/l10n/translationname, subject, body_html fields (all stored as JSONB)Follow the patterns in references/i18n-patterns.md:
from odoo import _ → _('Translatable string')import { _t } from "@web/core/l10n/translation" → _t("Translatable string")<field name="lang">{{ object.lang or 'cs_CZ' }}</field>Create i18n/ directory in the module with:
module_name.pot — POT template (optional but good practice)cs.po — Czech translationuk.po — Ukrainian translationen_US.po — English (for theme modules where source is not English)For website modules, ensure target languages are:
res_langwebsite_lang_rel (NOT website_res_lang_rel — that table doesn't exist)--load-language and --i18n-overwrite flagsPreferred approach: Create a settings_* companion module with XML data file that activates languages and sets website config. See references/i18n-patterns.md section 6, Option A.
CRITICAL Odoo 18 change: base.language.install wizard uses lang_ids (Many2many), NOT lang (Selection as in Odoo 16/17). Using the old lang field throws ValueError: Invalid field 'lang' on model 'base.language.install'.
python3 odoo-bin -d dbname -u module_name --stop-after-init \
--load-language=cs_CZ,uk_UA --i18n-overwrite
noupdate=True blocks template updates: If ir_model_data has noupdate=True for email templates, module upgrade won't overwrite them. Use direct SQL for production fixes.
Theme modules auto-create theme.ir.ui.view: <template> tags in theme modules create theme.ir.ui.view records, NOT ir.ui.view. Translation PO files reference model_terms:theme.ir.ui.view,arch.
JS translations need module upgrade: After creating PO files with code: references, run module upgrade with --i18n-overwrite to load them.
Email template lang field: Set <field name="lang">{{ object.lang or 'cs_CZ' }}</field> to enable per-record language selection. Store the customer's language on the model.
Missing DB columns after upgrade: If new fields are added but DB columns aren't created during upgrade, use manual ALTER TABLE as a fallback. Stale __pycache__ can cause this.
Provides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub michalvarys/claude-plugins --plugin odoo-dev-toolkit