Introduction
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
🎯 What does this module do?
The Menus module lets you retrieve site navigation structures - header menus, footer menus, sidebar navigation, mobile menus - dynamically building multi-level navigation from pages configured in OneEntry.
You create menus in the OneEntry admin panel (linking pages together) and this module fetches the complete menu tree, so you can render navigation dynamically without hardcoding links. The SDK is read-only for menus - you fetch them, you don't create them via code.
🚀 Quickstart
Initialize the module from defineOneEntry:
const { Menus } = defineOneEntry( "your-project-url", { "token": "your-app-token" });
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");
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);
});
✨ Key Concepts
What is a Menu?
A Menu (IMenusEntity) is a navigation structure that links pages together:
identifier- the menu marker (e.g."main_menu")localizeInfos- the localized menu titlepages- the array of menu items (each item is a page)
Menu Item Structure
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
position: 1, // Display order
children: [] // Nested menu items
}
Menu Hierarchy
Menus support nested structures. Nesting is expressed through each item's children[] array together with its parentId (top-level items have parentId: null). There is no separate depth field - you determine depth by walking children[].
📂 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)
📋 What You Need to Know
Menus are created in the admin panel
You cannot create menus via the SDK - they are created in the OneEntry admin panel (Menus → Create Menu → Add Pages → Save) or via the Admin API. The SDK is for fetching menu structures.
Menu items are pages
Every menu item is a page configured in OneEntry - you cannot add arbitrary links. To add an external link, create a page with an external URL in the Pages module and add it to the menu.
Sort by position
Items carry a position field - sort by it to respect the display order configured in the admin panel.
Multi-language
Menus are localized by the langCode passed to getMenusByMarker() (falling back to the language set in defineOneEntry()). Fetch menus in the user's preferred language.
📊 Quick Reference Table
| Method | Description | Use Case |
|---|---|---|
| getMenusByMarker() | Get menu by marker | Fetch a specific menu structure |
❓ Common Questions (FAQ)
How do I create a multi-level (dropdown) menu?
Build the menu tree in the admin panel by nesting pages. The nesting is returned through each item's children[] array - render it recursively.
Can I add external links to menus?
Menu items must be pages configured in OneEntry. To add an external link, create a page with an external URL in the Pages module, then add it to your menu.
How do I handle the active menu item state?
Compare the current page URL with each item's pageUrl and apply an active class when they match.
How do I build breadcrumbs?
Trace from the current page up through parentId relationships (Home > Category > Subcategory > Current Page).
Can I have different menus for different sections?
Yes - create multiple menus with different markers (e.g. header_menu, footer_menu, sidebar_menu) and fetch each with getMenusByMarker().
🎓 Best Practices
- Use markers, not IDs - markers are stable across environments.
- Render
children[]recursively - that is how nesting is represented. - Sort by
position- respect the configured display order. - Cache menus - they rarely change.
- Pass
langCode- fetch the menu in the user's language. - Handle missing menus gracefully - provide a fallback when the marker isn't found.
🔗 Related Documentation
- Pages Module - Manage the pages that make up your menus
- Locales Module - Multi-language support for menu localization
- GeneralTypes Module - Page types used in menus