Parallèle Docs
Api

Menus

API reference for menu endpoints.

Menus API

Menus provide navigation structures with nested items and multiple link types.

Get Menu

Fetch a navigation menu by slug.

GET /api/public/menus/:slug

Path Parameters

ParameterTypeRequiredDescription
slugstringYesMenu slug (e.g., main, footer)

Example

curl "https://parallele.ai/api/public/menus/main" \
  -H "x-api-key: prl_xxx"

Response:

{
  "menu": {
    "slug": "main",
    "name": "Main Navigation",
    "location": "header",
    "items": [
      {
        "id": "1",
        "label": "Home",
        "type": "PAGE",
        "url": "https://example.com/p/home",
        "openInNewTab": false,
        "icon": null,
        "children": []
      },
      {
        "id": "2",
        "label": "Products",
        "type": "URL",
        "url": "https://example.com/products",
        "openInNewTab": false,
        "icon": "box",
        "children": [
          {
            "id": "3",
            "label": "Software",
            "type": "URL",
            "url": "https://example.com/products/software",
            "openInNewTab": false,
            "icon": null,
            "children": []
          },
          {
            "id": "4",
            "label": "Services",
            "type": "URL",
            "url": "https://example.com/products/services",
            "openInNewTab": false,
            "icon": null,
            "children": []
          }
        ]
      },
      {
        "id": "5",
        "label": "Blog",
        "type": "BLOG",
        "url": "https://example.com/blog/latest-news",
        "openInNewTab": false,
        "icon": "newspaper",
        "children": []
      },
      {
        "id": "6",
        "label": "Contact",
        "type": "ANCHOR",
        "url": "#contact",
        "openInNewTab": false,
        "icon": "mail",
        "children": []
      }
    ]
  },
  "site": {
    "name": "My Website",
    "domain": "example.com"
  }
}
TypeDescriptionURL Format
PAGELinks to a CMS page/p/{slug} or full URL with domain
BLOGLinks to a blog post/blog/{slug} or full URL with domain
URLExternal or custom URLAs specified
ANCHORIn-page anchor link#{anchor}

Nested Structure

Menu items support unlimited nesting via the children array. This allows for dropdown menus and mega menus:

function NavMenu({ items }) {
  return (
    <nav>
      <ul>
        {items.map(item => (
          <NavItem key={item.id} item={item} />
        ))}
      </ul>
    </nav>
  );
}
 
function NavItem({ item }) {
  const hasChildren = item.children.length > 0;
 
  return (
    <li className={hasChildren ? "has-dropdown" : ""}>
      <a
        href={item.url}
        target={item.openInNewTab ? "_blank" : undefined}
        rel={item.openInNewTab ? "noopener noreferrer" : undefined}
      >
        {item.icon && <Icon name={item.icon} />}
        {item.label}
      </a>
      {hasChildren && (
        <ul className="dropdown">
          {item.children.map(child => (
            <NavItem key={child.id} item={child} />
          ))}
        </ul>
      )}
    </li>
  );
}

Common Menu Slugs

SlugTypical Usage
mainPrimary header navigation
footerFooter links
mobileMobile-specific navigation
legalLegal/policy links

Caching Menus

Menus rarely change, so aggressive caching is recommended:

// Next.js - cache for 1 hour
export const revalidate = 3600;
 
export default async function Layout({ children }) {
  const mainMenu = await parallele.getMenu("main");
  const footerMenu = await parallele.getMenu("footer");
 
  return (
    <>
      <Header menu={mainMenu} />
      {children}
      <Footer menu={footerMenu} />
    </>
  );
}

Icons

Menu items can include icon identifiers. The icon field contains a string that you can map to your icon library:

import {
  Home,
  Box,
  Newspaper,
  Mail,
  ExternalLink,
} from "lucide-react";
 
const iconMap = {
  home: Home,
  box: Box,
  newspaper: Newspaper,
  mail: Mail,
  external: ExternalLink,
};
 
function MenuIcon({ name }) {
  const Icon = iconMap[name];
  return Icon ? <Icon className="w-4 h-4" /> : null;
}

On this page