Contents
- Domma CMS User Manual
- 1. Using the CMS
- 2. Tutorials
- 3. Components
- 4. API Reference
- 5. Tools
Navigation API
Updated by Darryl Waterhouse on 29 September 2026 · 2 min read
The site's navigation is made of menus: each is a file in config/menus/<slug>.json, edited at Content > Menus, and shown by mapping it to a slot (the navbar, the footer) or placing it on a page with [menu slug="..." /]. The endpoints need the menus permission for the action named. The old single navigation file (config/navigation.json) was retired when menus arrived - see Legacy navigation at the end.
GET /api/menus
Requires Bearer token + menus read permission.
Every menu you may see (a user confined to some projects sees their projects' menus), without items.
GET /api/menus/:slug
Requires Bearer token + menus read permission.
One menu, with its items. Sub-items go under items.
// Response 200
{ "slug": "main", "name": "Main navigation", "variant": "dark", "position": "sticky",
"items": [
{ "text": "Home", "url": "/", "icon": "home" },
{ "text": "Services", "items": [ { "text": "Design", "url": "/design" } ] }
],
"meta": { "createdAt": "...", "updatedAt": "..." } }
POST /api/menus
Requires Bearer token + menus create permission.
Create a menu. slug is required; name, description, items and the display options (variant, position, orientation, align, side, float, highlight, binding) are optional. An item may carry visibility to show it only to some roles.
// Response 201 - the created menu
// Error 409
{ "error": "Menu \"main\" already exists" }
PUT /api/menus/:slug
Requires Bearer token + menus update permission.
Save a menu. The public pages that show it are refreshed.
DELETE /api/menus/:slug
Requires Bearer token + menus delete permission.
Delete a menu. Refused while it is mapped to a slot.
// Error 409
{ "error": "Cannot delete - menu is mapped to slot \"navbar\". Unmap it first." }
POST /api/menus/:slug/duplicate (create permission) makes a copy.
GET /api/menu-locations
Requires Bearer token + menus read permission.
Which menu fills each slot. GET /api/menu-locations/registry lists the slots there are (navbar, footer-primary, footer-legal, overlay, admin-sidebar, and any a plugin adds).
// Response 200
{ "navbar": "main", "footer-primary": "footer", "admin-sidebar": "admin-sidebar" }
PUT /api/menu-locations
Requires Bearer token + menus update permission.
Save the slot map (same shape as above).
// Response 200
{ "success": true }
GET /api/context-menus
Requires Bearer token + context-menus read permission.
Right-click menus for the public site (Content > Context Menus) are a separate kind of menu, with the same shape of routes: GET, POST /api/context-menus, GET, PUT, DELETE /api/context-menus/:slug, POST /api/context-menus/:slug/duplicate, and GET /api/context-menus/action-types for what an item can do.
Legacy navigation
GET and PUT /api/navigation (the navigation permission) still read and write config/navigation.json, but the public site no longer reads that file: on first start after menus arrived it was moved into the main menu and renamed navigation.json.bak. Use the menus endpoints above.