Skip to content

Odoo glossary

OWL

Also called Odoo Web Library, Owl, Owl framework, Odoo OWL component

Definition

OWL (Odoo Web Library) is the JavaScript UI framework Odoo builds and uses for its web client. OWL components are ES6 classes with a QWeb template and a setup() method, keep reactive state through hooks like useState, and are plugged into Odoo through registries such as fields, systray and main_components.

Open a sale order in Odoo 17, 18 or 19 and every piece of the screen, from the form renderer to each field, the dialogs and the systray icons, is an OWL component. Odoo develops the framework in its own repository, odoo/owl, and ships a copy inside the web module.

What a component looks like

A component is a class that extends Component. It names its template in static template, declares expected props in static props, and does its initialisation in setup(). Odoo’s docs are firm on that last point: don’t write a constructor, because a JavaScript constructor can’t be overridden the way Odoo code regularly overrides setup(). Hooks such as useState, onWillStart and Odoo’s own useService are called inside setup().

The template is QWeb syntax with a few extra directives like t-on-click, and it belongs in an XML file next to the JavaScript so it can be translated. Name it your_addon.ComponentName to avoid collisions.

Nothing reaches the browser until the files are listed in an asset bundle through the manifest, usually web.assets_backend.

A small field widget

A float field shown as a coloured percentage, for the margin_percent field that sale_margin adds to sale orders:

/** @odoo-module **/
import { Component } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { standardFieldProps } from "@web/views/fields/standard_field_props";

export class MarginBadgeField extends Component {
    static template = "sale_margin_badge.MarginBadgeField";
    static props = { ...standardFieldProps };

    get margin() {
        return this.props.record.data[this.props.name] || 0;
    }
}

export const marginBadgeField = {
    component: MarginBadgeField,
    supportedTypes: ["float"],
};

registry.category("fields").add("margin_badge", marginBadgeField);
<templates xml:space="preserve">
    <t t-name="sale_margin_badge.MarginBadgeField">
        <span t-attf-class="fw-bold {{ margin lt 0.18 ? 'text-danger' : 'text-success' }}"
              t-out="(margin * 100).toFixed(1) + '%'"/>
    </t>
</templates>

With both files under static/src and the folder added to web.assets_backend, an inherited form view uses it as <field name="margin_percent" widget="margin_badge"/>. The lt in the template is OWL’s word form of <, which saves escaping it in XML.

Version traps

The @odoo-module comment. Odoo 17 only transpiles a file as an ES module if it opens with that comment. From 18, every file under an addon’s static/src is handled as a module automatically. Keeping the comment is harmless, so code meant for 17 to 19 should have it.

Old registry format. In 16 you registered the component class itself in the fields registry. Since 17 the entry is an object with a component key plus metadata like supportedTypes and extractProps. Plenty of tutorials still show the old way.

Reading the wrong Owl docs. At the time of writing, the main branch of odoo/owl is an Owl 3 alpha with a signal-based API, while the 17.0, 18.0 and 19.0 branches of Odoo all bundle the same Owl 2 release. Use the Owl 2 docs, where state comes from useState.

When you don’t need one

Most requests for a custom widget are covered by what’s there: widget="badge", decoration-danger on list columns, or a progress bar widget. We’d check those first. When a widget is justified, erpfly writes it as part of the addon, next to the inherited view that uses it, and delivers both in one pull request. The Odoo customization page covers where widgets fit among other changes.

Sources

The official documentation and source code this page was checked against.

  1. 01 Owl components, Odoo 19 developer documentation odoo.com
  2. 02 Registries, Odoo 19 developer documentation odoo.com
  3. 03 Owl v2.8.4 README, odoo/owl on GitHub github.com
  4. 04 odoo/tools/js_transpiler.py (18.0), odoo/odoo on GitHub github.com

Where OWL comes up

Terms used on this page

More Odoo terms

Your next module is one paragraph away

Write it the way you’d explain it to a new hire. We’ll turn it into an app you can read, test and install.

Odoo 19

Create your account

Free to start. No card needed.

By signing up you agree to our terms and privacy policy.