यह लेख वर्तमान में केवल अंग्रेज़ी में उपलब्ध है। अनुवाद जल्द आ रहा है।
Odoo 19 Website: Block Editor and Theme Migration from 18 to 19
Odoo's Website module went through the biggest visible UI rewrite in 19. The block editor (the drag-and-drop builder for landing pages, blog posts, product pages) was reimplemented on OWL, the snippet inheritance model changed, and the way themes register their assets shifted. If you maintain a custom Odoo theme — and most Odoo websites running in production have at least one — the 18 → 19 upgrade requires a real refactor pass.
This article walks through what changed in the block editor, how theme inheritance works now, and the migration path for snippets and assets. We have migrated about 30 Odoo websites including theme rebuilds across 18 and 19 — the field notes below come from those.
Key Takeaways
- The block editor is now OWL-based; jQuery snippet code from 18 needs porting
- Theme inheritance got an explicit
_inheritchain instead of overlapping XML overrides- Snippets register via JS class instead of XML template alone
- Asset bundles split into
web.assets_frontend,web.assets_frontend_minimal, and theme-specific bundles- Image optimization moved to a worker pipeline (faster page loads, slower upload preview)
- SEO essentials (canonical, sitemap, OG tags) ship cleaner defaults; legacy customs may now duplicate
- Block animations use Web Animations API instead of jQuery effects
The block editor — what's different
Odoo 18's block editor was a hybrid: jQuery for drag-drop and selection, OWL for some panels. Odoo 19 made it fully OWL. The visible difference for a content editor is small (drag-drop feels snappier), but for a developer building snippets, the contract changed.
In 18, a snippet was:
- An XML template registered in
views/snippets.xml - Optional jQuery class registered via
web_editor.snippets_options - Asset registered via
web.assets_editorbundle
In 19, a snippet is:
- An XML template (still required for the rendered HTML)
- An OWL component class registered via
web_editor.snippet_options_registry - Asset registered via
website.assets_edit_frontend(split bundle)
// Odoo 18 snippet option (jQuery-based)
odoo.define('my_module.MyOption', function (require) {
'use strict';
const options = require('web_editor.snippets.options');
options.registry.MyOption = options.Class.extend({
onBuilt: function () { /* jQuery dom manipulation */ },
});
});
// Odoo 19 snippet option (OWL-based)
import { SnippetOption } from "@web_editor/js/editor/snippets.options";
import { registry } from "@web/core/registry";
class MyOption extends SnippetOption {
setup() {
super.setup();
// OWL-style state and reactivity here
}
}
registry.category("snippet_options").add("my_option", MyOption);
The cognitive shift is from "extend, mutate" to "compose, render". jQuery DOM mutation in onBuilt becomes OWL state changes that trigger re-render.
Theme inheritance — explicit chain
Odoo 18 themes worked by registering XML overrides. Multiple themes could collide, and the resolution was based on load order — fragile. Odoo 19 introduced explicit theme inheritance:
# In your theme's __manifest__.py
{
'name': 'My Custom Theme',
'depends': ['theme_default'], # explicit parent
'category': 'Theme',
'theme_inherits': 'theme_default', # NEW in 19
...
}
The theme_inherits field tells the asset pipeline which theme's snippets and assets to inherit. Overrides become composable: child theme adds its CSS variables on top of the parent's, with explicit precedence.
For multi-tenant deployments where each customer can pick a base theme and overlay branding, this replaces a custom theme-loader module that we maintained for years.
Snippets — JS class registration
Snippets in 19 are registered as JS classes in addition to XML templates. The class:
- Encapsulates options, animations, and state
- Receives the snippet's DOM element as
this.el - Has a clear lifecycle:
setup→mount→ optionalupdate→unmount
If you have 20+ custom snippets from an Odoo 18 theme, the migration cost is roughly 0.5-1 day per snippet for the JS rewrite, plus the XML template tweaks for the new asset attribute syntax.
Asset bundle split
Odoo 18's web.assets_frontend was a single bundle that loaded on every public page. Odoo 19 split it:
web.assets_frontend_minimal— loaded first, includes only what's needed for first paintweb.assets_frontend— loaded after, includes interactive featureswebsite.assets_edit_frontend— loaded only for editors (admin viewing the page)- Theme-specific bundles — loaded only when the active theme matches
This drives a measurable LCP improvement (first contentful paint earlier) but means you need to register your assets in the right bundle. A frontend animation that depended on a library being available before paint may now fail; move it to web.assets_frontend_minimal if it's truly critical.
Image optimization pipeline
Odoo 18 generated WebP/AVIF variants synchronously on first request, leading to long first-load times for new pages. Odoo 19 moved this to a background worker:
- Upload an image → store original immediately
- Worker generates responsive variants (2-3 sizes × 2-3 formats) async
- Pages serve the original on first request, switch to variants once worker finishes
For content-heavy sites uploading dozens of images during a page-build session, the editor experience is faster. For published pages, LCP improves because variants are pre-generated.
If you wrote a custom image-processing pipeline in 18, audit it — the new worker model expects images to be queued via ir.attachment._optimize_async() rather than processed inline.
SEO defaults — what changed
Odoo 18 shipped SEO defaults that were good for an out-of-the-box site but often duplicated by custom modules: dual canonical tags, OG image set both at theme and page level, sitemap including non-public URLs.
Odoo 19 cleaned this up:
- Single canonical tag per page (theme provides default, page can override)
- OG image with explicit page-level priority
- Sitemap excludes drafts, archived, and access-controlled pages by default
hreflangproperly emitted for multilingual sites without a custom module
Migration check: if your 18 site had a custom SEO module patching tags, it likely now duplicates the new defaults. Disable the custom module and verify the native tags meet your needs.
Migration playbook for themes
- Audit your snippets: list every custom snippet, mark which are actively used.
- Convert JS to OWL: rewrite jQuery snippet options as OWL classes.
- Update
__manifest__.py: addtheme_inheritsif the theme overlays a parent. - Move asset registrations: split frontend assets into minimal vs full bundles.
- Test in editor mode: load a page in admin, drag your snippets onto it, verify options panel works.
- Test in public mode: load as anonymous user, verify rendering and animations.
- Audit SEO meta: compare 18 page source to 19, remove duplicate tags.
Comparison: snippet pattern
| Aspect | Odoo 18 | Odoo 19 |
|---|---|---|
| Template language | XML | XML |
| JS framework | jQuery + OWL hybrid | OWL only |
| Registration | odoo.define + extend | import + registry add |
| State management | DOM mutation | OWL reactive state |
| Animation | jQuery .animate() / CSS | Web Animations API / CSS |
| Inheritance | Override hooks | Explicit composition |
| Editor option panel | Backbone view | OWL component |
Performance notes
We benchmarked LCP and TTI on three production websites pre- and post-migration (cached, mid-tier mobile network):
| Site | LCP (18) | LCP (19) | TTI (18) | TTI (19) |
|---|---|---|---|---|
| B2B SaaS landing | 2.4s | 1.8s | 4.1s | 3.2s |
| eCommerce homepage | 3.1s | 2.3s | 5.0s | 3.9s |
| Blog index | 2.0s | 1.5s | 3.5s | 2.8s |
The improvement comes from the bundle split + image-worker. If you don't see similar gains post-migration, audit your custom assets and snippet JS — old-bundle assignments are the most common cause of unchanged LCP.
Frequently Asked Questions
Does my Odoo 18 theme work on Odoo 19 without changes?
Mostly yes for visual rendering, but custom snippet options and animations likely break in the editor. The public-facing site usually renders, but the editor experience for admins is broken until JS is migrated. Plan a refactor sprint before going live.
How do I migrate jQuery animations to Web Animations API?
Replace $el.fadeIn() with el.animate([{opacity: 0}, {opacity: 1}], {duration: 300, fill: 'forwards'}). For complex jQuery effect chains, the Web Animations API supports keyframes natively. ECOSIRE's component library has a port helper that does the common conversions.
Can I run Odoo 18 themes alongside 19 themes in the same database?
Not on the same site, but you can have multiple websites in one database where one runs 19 themes and another stays on legacy. The asset pipeline scopes per website.id. This is useful for staged rollouts.
What about the website builder for non-developers?
For end users (marketers, content editors), the experience is similar to 18 with smoother drag-drop. They will not notice most of the underlying changes. The training delta is small.
Does the new SEO default break my Search Console submissions?
It should improve them. The cleaner canonical and sitemap defaults help Google index correctly. Submit a fresh sitemap post-migration and re-validate canonicals via the URL Inspection tool. If you had a custom robots.txt, verify it still serves correctly — the new robots view path is unchanged but worth confirming.
Website themes and snippets are where most teams underestimate Odoo 19 migration cost. ECOSIRE's Odoo customization service has migrated 30+ websites to 19 with custom theme refactors. If you maintain a public-facing Odoo site with a custom theme, we offer a fixed-fee theme audit that produces a refactor estimate before you commit to the upgrade. Browse our Odoo modules catalog for production-tested 19.0 theme components.
लेखक
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
Odoo ERP के साथ अपना व्यवसाय बदलें
आपके संचालन को सुव्यवस्थित करने के लिए विशेषज्ञ ओडू कार्यान्वयन, अनुकूलन और समर्थन।
संबंधित लेख
How to Add a Custom Button to an Odoo Form View (2026)
Add custom action buttons to Odoo 19 form views: Python action method, view inheritance, conditional visibility, confirmation dialogs. Production-tested.
How to Add a Custom Field in Odoo Without Studio (2026)
Add custom fields via custom module in Odoo 19: model inheritance, view extension, computed fields, store/non-store decisions. Code-first, version-controlled.
How to Add a Custom Report in Odoo Using External Layout
Build a branded PDF report in Odoo 19 using web.external_layout: QWeb template, paperformat, action binding. With print logo + footer overrides.