Getting Elements

Menu Queries

You can fetch menus in your templates or PHP code using menu queries.

{# Create a new menu query #}
{% set myQuery = craft.navigation.menu('mainMenu') %}
// Create a new menu query
$myQuery = \verbb\navigation\elements\Menu::find();

Once you’ve created a menu query, you can set parameters on it to narrow down the results, and then execute it by calling .all(). An array of Menu objects will be returned.

A Menu element holds the values of a menu's own custom fields, such as a heading or promo image shown in a mega menu. The links in the menu are nodes, which you fetch with node queries. For a menu's settings, such as its maximum levels, see Menu Settings.

craft.navigation.menu() takes a menu handle and returns a menu query with the handle parameter already set, so you'll usually finish it with .one(). Pass null instead of a handle to query every menu.

See Element Queries (opens new window) in the Craft docs to learn about how element queries work.

Example

We can display a mega menu's promo content by doing the following.

  1. Create a menu query with craft.navigation.menu(), passing the menu's handle.
  2. Fetch the menu with .one().
  3. Output its menu-level fields, here a promoHeading text field and a promoImage Assets field.
{# Create a menu query for the main menu, and fetch it #}
{% set menu = craft.navigation.menu('mainMenu').one() %}

{% if menu %}
    <h2>{{ menu.promoHeading }}</h2>

    {% set image = menu.promoImage.one() %}

    {% if image %}
        <img src="{{ image.url }}" alt="{{ image.alt }}">
    {% endif %}
{% endif %}

Menus don't have statuses, so there's no status parameter, and a menu query returns every menu that matches.

Getting a Menu by Handle or ID

When you only need one menu and know which, craft.navigation has shortcuts that run the query for you. craft.navigation.getMenuByHandle(handle) returns the Menu element with that handle, the same as craft.navigation.menu(handle).one(). craft.navigation.getMenuById(id) does the same for a menu ID, which is useful when a template only has an ID to go on, such as one saved in a Number field. Both return null when no menu matches. craft.navigation.getAllMenus() returns every menu as an array.

This example assumes the entry has a Number field with the handle promoMenuId, holding the ID of the menu whose promo heading the page shows:

{% set menu = entry.promoMenuId ? craft.navigation.getMenuById(entry.promoMenuId) : null %}

{% if menu %}
    <h2>{{ menu.promoHeading }}</h2>
{% endif %}

All three return Menu elements, which hold field values. For a menu's settings, such as its maximum levels, use Menu Settings in PHP instead.

When you already have a node, you don't need either shortcut, because node.menu returns the menu the node belongs to.

Parameters

Menu queries support the following parameters.

asArray

Causes the query to return matching menus as arrays of data, rather than Menu objects.

{# Fetch menus as arrays #}
{% set menus = craft.navigation.menu(null)
    .asArray()
    .all() %}
// Fetch menus as arrays
$menus = \verbb\navigation\elements\Menu::find()
    ->asArray()
    ->all();

dateCreated

Narrows the query results based on the menus’ creation dates.

ValueFetches menus…
'>= 2026-04-01'that were created on or after 2026-04-01.
'< 2026-05-01'that were created before 2026-05-01.
['and', '>= 2026-04-01', '< 2026-05-01']that were created between 2026-04-01 and 2026-05-01.
{# Fetch menus created this year #}
{% set menus = craft.navigation.menu(null)
    .dateCreated('>= 2026-01-01')
    .all() %}
// Fetch menus created this year
$menus = \verbb\navigation\elements\Menu::find()
    ->dateCreated('>= 2026-01-01')
    ->all();

dateUpdated

Narrows the query results based on the menus’ last-updated dates, which change when menu-level field values are saved.

ValueFetches menus…
'>= 2026-04-01'that were updated on or after 2026-04-01.
'< 2026-05-01'that were updated before 2026-05-01.
{# Fetch menus updated in the last week #}
{% set menus = craft.navigation.menu(null)
    .dateUpdated('>= ' ~ now|date_modify('-7 days')|atom)
    .all() %}
// Fetch menus updated in the last week
$menus = \verbb\navigation\elements\Menu::find()
    ->dateUpdated('>= ' . (new \DateTime('-7 days'))->format(\DateTime::ATOM))
    ->all();

fixedOrder

Causes the query results to be returned in the order specified by id.

{# Fetch menus in a specific order #}
{% set menus = craft.navigation.menu(null)
    .id([3, 1, 2])
    .fixedOrder()
    .all() %}
// Fetch menus in a specific order
$menus = \verbb\navigation\elements\Menu::find()
    ->id([3, 1, 2])
    ->fixedOrder()
    ->all();

handle

Narrows the query results based on the menus’ handles. craft.navigation.menu('mainMenu') sets this parameter for you.

ValueFetches menus…
'mainMenu'with a handle of mainMenu.
['mainMenu', 'footerMenu']with a handle of mainMenu or footerMenu.
'not mainMenu'not with a handle of mainMenu.
{# Fetch the main and footer menus #}
{% set menus = craft.navigation.menu(null)
    .handle(['mainMenu', 'footerMenu'])
    .all() %}
// Fetch the main and footer menus
$menus = \verbb\navigation\elements\Menu::find()
    ->handle(['mainMenu', 'footerMenu'])
    ->all();

id

Narrows the query results based on the menus’ element IDs.

ValueFetches menus…
1with an ID of 1.
'not 1'not with an ID of 1.
[1, 2]with an ID of 1 or 2.
{# Fetch the menu by its ID #}
{% set menu = craft.navigation.menu(null)
    .id(1)
    .one() %}
// Fetch the menu by its ID
$menu = \verbb\navigation\elements\Menu::find()
    ->id(1)
    ->one();

inReverse

Causes the query results to be returned in reverse order.

{# Fetch menus in reverse #}
{% set menus = craft.navigation.menu(null)
    .inReverse()
    .all() %}
// Fetch menus in reverse
$menus = \verbb\navigation\elements\Menu::find()
    ->inReverse()
    ->all();

limit

Determines the number of menus that should be returned.

{# Fetch up to 5 menus #}
{% set menus = craft.navigation.menu(null)
    .limit(5)
    .all() %}
// Fetch up to 5 menus
$menus = \verbb\navigation\elements\Menu::find()
    ->limit(5)
    ->all();

Narrows the query results based on the menus’ handles. It's an alias of handle.

{# Fetch the footer menu #}
{% set menu = craft.navigation.menu(null)
    .menuHandle('footerMenu')
    .one() %}
// Fetch the footer menu
$menu = \verbb\navigation\elements\Menu::find()
    ->menuHandle('footerMenu')
    ->one();

offset

Determines how many menus should be skipped in the results.

{# Fetch all menus except the first #}
{% set menus = craft.navigation.menu(null)
    .offset(1)
    .all() %}
// Fetch all menus except the first
$menus = \verbb\navigation\elements\Menu::find()
    ->offset(1)
    ->all();

orderBy

Determines the order that the menus should be returned in. Menus are returned newest first unless you set an order.

{# Fetch menus by their sort order #}
{% set menus = craft.navigation.menu(null)
    .orderBy('navigation_menus.sortOrder asc')
    .all() %}
// Fetch menus in alphabetical order
$menus = \verbb\navigation\elements\Menu::find()
    ->orderBy('navigation_menus.sortOrder asc')
    ->all();

site

Determines which site the menus should be queried in. Menu-level field values can differ between sites, so this controls which site’s values you get. The current site is used by default.

ValueFetches menus…
'foo'from the site with a handle of foo.
a craft\models\Site objectfrom the site represented by the object.
{# Fetch the main menu from the Foo site #}
{% set menu = craft.navigation.menu('mainMenu')
    .site('foo')
    .one() %}
// Fetch the main menu from the Foo site
$menu = \verbb\navigation\elements\Menu::find()
    ->handle('mainMenu')
    ->site('foo')
    ->one();

siteId

Determines which site the menus should be queried in, by the site’s ID. The current site is used by default.

{# Fetch the main menu from the site with an ID of 1 #}
{% set menu = craft.navigation.menu('mainMenu')
    .siteId(1)
    .one() %}
// Fetch the main menu from the site with an ID of 1
$menu = \verbb\navigation\elements\Menu::find()
    ->handle('mainMenu')
    ->siteId(1)
    ->one();

uid

Narrows the query results based on the menus’ element UIDs.

{# Fetch the menu by its UID #}
{% set menu = craft.navigation.menu(null)
    .uid('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')
    .one() %}
// Fetch the menu by its UID
$menu = \verbb\navigation\elements\Menu::find()
    ->uid('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')
    ->one();

with

Causes the query to return matching menus eager-loaded with related elements from their menu-level fields, such as an Assets field on the menu.

{# Fetch the main menu with its promo image eager-loaded #}
{% set menu = craft.navigation.menu('mainMenu')
    .with(['promoImage'])
    .one() %}
// Fetch the main menu with its promo image eager-loaded
$menu = \verbb\navigation\elements\Menu::find()
    ->handle('mainMenu')
    ->with(['promoImage'])
    ->one();