menu
Fetches the header and footer menus the merchant built in the Salla dashboard, in the language of the current page.
import { menu } from '@salla.sa/twilight-theme-engine/api/menu';In plain words
Merchants build their store's navigation in the Salla dashboard: which categories and pages appear in the header, which links go in the footer. menu.header() and menu.footer() return those lists, each item with a title, a url and, for dropdowns, children.
They always answer in the language of the page being rendered; you never pass a language.
Signature
menu.header(): Promise<MenuItem[]> // GET menus/header?lang=<page locale>
menu.footer(): Promise<MenuItem[]> // GET menus/footer?lang=<page locale>
menu.queries.header() // key ['menus', 'header', locale], staleTime 5 min
// there is no menu.queries.footer()
interface MenuItem {
id: number | string;
title: string;
url: string;
children?: MenuItem[];
has_children?: boolean;
}Try it live
Loading the header menu…
import { useQuery } from '@tanstack/react-query';
import { menu } from '@salla.sa/twilight-theme-engine/api/menu';
import { Link } from '@salla.sa/twilight-theme-engine/components/common';
export function MainNav() {
const { data = [] } = useQuery(menu.queries.header());
return (
<ul className="main-nav">
{data.map((item) => (
<li key={item.id}>
<Link to={item.url}>{item.title}</Link>
</li>
))}
</ul>
);
}
Example
import { useQuery } from '@tanstack/react-query';
import { menu } from '@salla.sa/twilight-theme-engine/api/menu';
import { Link } from '@salla.sa/twilight-theme-engine/components/common';
export function MainNav() {
const { data = [] } = useQuery(menu.queries.header());
return (
<ul className="main-nav">
{data.map((item) => (
<li key={item.id ?? item.url}>
<Link to={item.url}>{item.title}</Link>
</li>
))}
</ul>
);
}
How it behaves
The language is
getTwilightContext().locale(set by the root loader), sent as?lang=.menu.queries.header()reads it when called, so build the options during render, not once at module level.Both functions return
data || [], so a missing menu is an empty array. Both endpoints are public.The engine
MainMenuandMobileMenureadmenu.queries.header(). The engine footer does not usemenu.footer(): it renders Salla's own menu web component.Live items carry more than the type declares:
target,order,image, andattrs/link_attrsas raw HTML attribute strings (demo store).
Gotchas
There is no
menu.queries.footer(). Build the options yourself and key them on the locale (['menus', 'footer', locale]); a key without the locale can hand the Arabic footer to the English page from the cache.idis not a safe React key on its own: header items mix numbers (category ids) and words ("offers"), footer page links use paths ("about-us/page-1061977328"), and a footer item can have noidat all (the blog link on the demo store). Fall back tourl.
Related
Loads one of the merchant's own content pages, such as About us or the privacy policy, by its page id.
categoryReads the store's category tree, or a single category, from the Salla API; the tree is cached per branch.
HeaderThe storefront header: top bar with search and language, logo, main menu, account and cart, built from the store's data.
Source and docs
- Engine source:
packages/theme-engine/src/api/menu.ts