Ad – 728×90
⚙️ Module Development

Odoo Menus and Actions – Building the Navigation Structure

Every entry in Odoo's navigation bar is a menu item. Every menu item triggers an action — most commonly a window action that opens a model in a view. This page covers how to define window actions, how to build the menu hierarchy, and how to use server actions, URL actions, and client actions to extend your module's navigation.

⏱️ 20 min 🎯 Beginner 📅 Updated 2026

Window Actions (ir.actions.act_window)

A window action opens a model in one or more view types. It is the most common action type.

XML
<record id="action_library_book" model="ir.actions.act_window">
    <field name="name">Books</field>
    <field name="res_model">library.book</field>
    <field name="view_mode">list,kanban,form</field>

    <!-- Optional: filter records shown -->
    <field name="domain">[('active', '=', True)]</field>

    <!-- Optional: pass context to views (activate default filters, set defaults) -->
    <field name="context">{
        'search_default_available': 1,
        'default_state': 'available'
    }</field>

    <!-- Optional: force a specific view for one of the modes -->
    <field name="view_id" ref="view_library_book_list"/>
</record>
FieldPurpose
nameDisplay name in the breadcrumb and window title
res_modelThe model to open
view_modeComma-separated list of allowed view types
domainPermanent filter applied to all records shown
contextDict passed to views; search_default_X activates filter X; default_field sets new-record defaults
view_idForce a specific view for the first view mode
targetcurrent (default), new (popup dialog), fullscreen, main

Menu items are the navigation entries in the top bar and sidebar. They form a hierarchy:

XML
<!-- Level 1: Top-level app menu (visible in the main hamburger menu) -->
<menuitem id="menu_library_root"
          name="Library"
          web_icon="library_management,static/description/icon.png"
          sequence="50"/>

<!-- Level 2: Section heading (no action — just groups sub-items) -->
<menuitem id="menu_library_catalog"
          name="Catalog"
          parent="menu_library_root"
          sequence="10"/>

<!-- Level 3: Actual clickable item that opens a view -->
<menuitem id="menu_library_books"
          name="Books"
          parent="menu_library_catalog"
          action="action_library_book"
          sequence="10"/>

<menuitem id="menu_library_categories"
          name="Categories"
          parent="menu_library_catalog"
          action="action_library_category"
          sequence="20"/>

<!-- Level 2: Configuration section -->
<menuitem id="menu_library_config"
          name="Configuration"
          parent="menu_library_root"
          sequence="90"
          groups="base.group_system"/>

<menuitem id="menu_library_config_settings"
          name="Settings"
          parent="menu_library_config"
          action="action_library_settings"
          sequence="10"/>
AttributePurpose
idXML ID for referencing
nameDisplay label
parentParent menuitem XML ID (omit for root)
actionXML ID of the action to trigger when clicked
sequenceSort order (lower number = appears first)
groupsRestrict visibility to specific user groups
web_iconModule icon for top-level app menus
💡
menuitem shorthand

<menuitem> does not need a <record> wrapper — it is its own shorthand element. The action attribute takes just the local XML ID within the same module, or module_name.xml_id for cross-module references.

Ad – 336×280

Other Action Types

Besides window actions, Odoo has four other action types.

Server Action (ir.actions.server) — runs Python code:

XML
<record id="action_server_send_reminders" model="ir.actions.server">
    <field name="name">Send Overdue Reminders</field>
    <field name="model_id" ref="model_library_book"/>
    <field name="binding_model_id" ref="model_library_book"/>
    <field name="state">code</field>
    <field name="code">
        records.action_send_overdue_reminders()
    </field>
</record>

When binding_model_id is set, this action appears in the Action menu (⚙️) on the list and form views of that model.

URL Action (ir.actions.act_url) — opens a URL:

XML
<record id="action_open_docs" model="ir.actions.act_url">
    <field name="name">Open Documentation</field>
    <field name="url">https://algorid.com/docs</field>
    <field name="target">new</field>  <!-- new tab -->
</record>

Client Action (ir.actions.client) — loads a custom OWL JS component:

XML
<record id="action_library_dashboard" model="ir.actions.client">
    <field name="name">Library Dashboard</field>
    <field name="tag">library_management.LibraryDashboard</field>
</record>

Report Action (ir.actions.report) — generates a QWeb PDF:

XML
<record id="action_report_library_book" model="ir.actions.report">
    <field name="name">Book Card</field>
    <field name="model">library.book</field>
    <field name="report_type">qweb-pdf</field>
    <field name="report_name">library_management.report_book_document</field>
    <field name="binding_model_id" ref="model_library_book"/>
</record>

Correct File Load Order

Menus that reference actions, and actions that reference views, must be loaded in the correct order. The manifest data list must be:

Python
'data': [
    'security/ir.model.access.csv',    # 1. Security first
    'views/book_views.xml',            # 2. Views
    'views/member_views.xml',
    'views/actions.xml',               # 3. Actions (reference views)
    'views/menus.xml',                 # 4. Menus (reference actions)
    'report/book_report.xml',          # 5. Reports
    'data/book_sequence.xml',          # 6. Default data last
],

Using Context for Defaults and Filters

The context field on a window action is extremely powerful:

XML
<record id="action_my_books" model="ir.actions.act_window">
    <field name="name">My Books</field>
    <field name="res_model">library.book</field>
    <field name="view_mode">list,form</field>
    <field name="context">{
        'search_default_my_books': 1,
        'search_default_available': 1,
        'default_librarian_id': uid,
        'default_state': 'available'
    }</field>
</record>
  • search_default_X — automatically activates a filter named X in the search view (the name attribute on the <filter> element)
  • default_fieldname — sets the default value for fieldname when creating new records through this action
  • uid — the current user's ID (available in context expressions)

📋 Key Points

  • Window actions (ir.actions.act_window) open a model in view modes specified by view_mode
  • <menuitem> elements build the navigation hierarchy; leaf items link to an action by XML ID
  • Use sequence to control order; lower numbers appear first
  • Use groups on menu items to restrict visibility by user group
  • Other action types: server (Python code), URL (open a link), client (OWL component), report (PDF)
  • Load order in manifest: security → views → actions → menus → data

FAQ

What is the difference between target="new" and target="current" on a window action? +

target="current" (default) opens the view in the main content area, replacing what was there. target="new" opens the action in a modal dialog (popup). Use "new" for wizard-style flows, confirmations, and quick-create forms. Use "current" for main navigation flows.

Can a menu item exist without an action? +

Yes. A menu item without an action attribute is a non-clickable section header — it just groups child items visually. This is common for parent-level menus like "Configuration" or "Reporting".

How do I add my action to the top Action menu (⚙️ gear) on a model's views? +

Set binding_model_id on the action: <field name="binding_model_id" ref="model_my_model"/>. This binds the action to that model's views. Server actions and report actions can both be bound this way. The model_ prefix + model name with dots→underscores is the auto-generated XML ID for the ir.model record.

What does web_icon do on a root menuitem? +

It sets the icon shown on the app tile in the main Apps home screen. The value format is module_name,path/to/icon.png. The icon should be 128×128 pixels, placed at static/description/icon.png in your module.