menu

Fetch the store's header and footer navigation menus in the current language.

Use menu to build navigation from the menus the merchant set up.

app/components/HeaderNav.tsx
import { useQuery } from '@tanstack/react-query';
import { menu } from '@salla.sa/twilight-theme-engine/api/menu';

export function HeaderNav() {
  const { data: items = [] } = useQuery(menu.queries.header());

  return (
    <nav>
      {items.map((item) => (
        <a key={item.id} href={item.url}>{item.title}</a>
      ))}
    </nav>
  );
}

Methods

MethodParametersReturnsRequestLogin needed
menu.headernonePromise<MenuItem[]>GET menus/header?lang={locale}No
menu.footernonePromise<MenuItem[]>GET menus/footer?lang={locale}No

Both send the current locale as the lang parameter, on top of the accept-language header every request carries.

Queries

QueryKey
queries.header()['menus', 'header', locale]

The key includes the locale but not the scope. The query is fresh for 5 minutes. There is no queries.footer: call menu.footer() directly, or wrap it in your own queryOptions.

app/routes/__root.tsx
import { getTwilightContext } from '@salla.sa/twilight-theme-engine/tanstack';
import { menu } from '@salla.sa/twilight-theme-engine/api/menu';

loader: async () => {
  const { queryClient } = getTwilightContext();
  const [header, footer] = await Promise.all([
    queryClient.ensureQueryData(menu.queries.header()),
    menu.footer(),
  ]);
  return { header, footer };
},

Gotchas

  • Both methods return [] when the response has no data.
  • Errors are not caught: failures throw HTTPError or TimeoutError.
  • The locale comes from the twilight context, so call these inside a running app, not from a standalone script.

See also

On this page