Skip to main content

Menus

Fetch multi-level site navigation menus built from pages configured in OneEntry.

More information about the module's user interface https://doc.oneentry.cloud/docs/category/menu (opens in a new tab)


The Menus module returns navigation structures such as header, footer, sidebar and mobile menus.

You create menus in the OneEntry admin panel (Menus → Create Menu → Add Pages → Save) or through the Admin API, and this module fetches the whole menu tree, so you can render navigation without hardcoding links. The SDK only reads menus.

Quickstart​

Initialize the module from defineOneEntry:


const { } = defineOneEntry(
, {
}
);

Fetch a menu by its marker and walk its pages:

// Fetch the "main_menu" structure in English.
const menu = await Menus.getMenusByMarker("main_menu", "en_US");
if ('statusCode' in menu) throw new Error(menu.message);

console.log(menu.identifier, menu.localizeInfos.title);

// Top-level items; nested items live in each item's children[].
menu.pages.forEach((item) => {
console.log(item.pageUrl, item.localizeInfos.title, item.children);
});

A menu (IMenusEntity) is a navigation structure that links pages together:

  • identifier: the menu marker (e.g. "main_menu")
  • localizeInfos: the localized menu title
  • pages: the menu items: pages and custom items

A menu holds pages configured in OneEntry and custom items; itemType tells them apart (see below). To add an external link, create a page of type external_page in the Pages module and add it to the menu. To have different menus for different sections, create several menus with different markers (e.g. header_menu, footer_menu, sidebar_menu) and fetch each with getMenusByMarker().

Each item in pages is an IMenusPages object:

{
id: 123, // Page ID
pageUrl: "home", // Page URL (marker)
localizeInfos: { title: "Home" },
attributeValues: {}, // Custom attribute values
parentId: null, // null for top-level items
parentType: null, // "page" | "custom" | null - kind of the parent
itemType: "page", // "page" | "custom" - kind of this item
position: 1, // Display order
children: [] // Nested menu items
}

Items have a position field. Sort by it to keep the display order configured in the admin panel.

Nesting​

Menus can be nested. Nesting is expressed through each item's children[] array together with its parentId (top-level items have parentId: null). There is no depth field; you get the depth by walking children[]. To build a multi-level (dropdown) menu, nest pages in the admin panel and render children[] recursively.

Header Menu
├─ Home (parentId: null)
├─ About (parentId: null)
│ ├─ Team (parentId: 2)
│ └─ History (parentId: 2)
├─ Products (parentId: null)
│ └─ Electronics (parentId: 4)
│ ├─ Phones (parentId: 5)
│ └─ Laptops (parentId: 5)
└─ Contact (parentId: null)

To mark the active item, compare the current page URL with each item's pageUrl. To build breadcrumbs, follow parentId up from the current page (Home > Category > Subcategory > Current Page).

Two kinds of menu item: itemType and parentType​

A menu holds two kinds of item, menu pages and custom items, and their ids come from different sequences, so they overlap: parentId: 5 alone doesn't tell you whether the parent is the page with id 5 or the custom item with id 5.

Two fields resolve that:

  • itemType ('page' | 'custom'): what this item itself is.
  • parentType ('page' | 'custom' | null): what its parent is. null together with parentId: null means the item is top-level.

A custom item has the same shape as a page item: its pageUrl holds the value you set for it (for example an external link), attributeValues is empty, and localizeInfos repeats the title as menuTitle with empty htmlContent and plainContent. Check itemType before you treat pageUrl as a page marker.

An item's children carry its itemType as their parentType, so match on the pair when you rebuild the tree yourself:

const childrenOf = (items, parent) =>
items.filter(
(item) => item.parentId === parent.id && item.parentType === parent.itemType,
);

Languages​

Menus are localized by the langCode you pass to getMenusByMarker(), falling back to the language set in defineOneEntry(). Fetch menus in the user's language. Reference menus by marker rather than ID (markers are stable across environments), cache them (they rarely change), and render a fallback when a marker isn't found.


Methods​

MethodDescriptionUse Case
getMenusByMarker()Get menu by markerFetch a specific menu structure