Menus and navigation
Create menus, connect links and style navigation.
Where menu items come from
Create items in the site's Navigation panel. Assign a menu to header or footer, enter labels and destinations, arrange the order and save. Do not package customer menu IDs. These locations work with Loom and the application's shared header.
Ready-to-use Loom element
<gs-menu location="header" label="Main navigation" class="theme-menu"></gs-menu>
<gs-menu location="footer" label="Useful links"></gs-menu>The element renders nav, a ul and anchors. label names the navigation for screen readers. Do not nest it inside another nav. It does not create pages or menu entries. In editor preview, links do not leave the builder. Public rendering applies the site prefix and custom-domain rules. An assigned empty menu stays empty; without an assignment, public rendering can fall back to page links.
The shared site header still displays the main navigation. Use this element for additional navigation in a section or footer; adding gs-menu does not disable that header. Avoid placing duplicate menus next to each other.
Custom markup and styling
<ul class="secondary-links">
<template gs-repeat="item in menus.footer">
<li><a href="[[ safe_url(item.href) ]]" gs-text="item.label"></a></li>
</template>
</ul>menus.header and menus.footer expose label and href. Text is escaped automatically. Do not prepend a domain: the renderer already resolves destinations. Snippets receive the menus context without extra arguments.
.theme-menu ul { display:flex; flex-wrap:wrap; gap:1rem; padding:0; list-style:none; }
.theme-menu a:focus-visible { outline:2px solid currentColor; outline-offset:4px; }Before publication
Test empty menus, long labels, narrow screens, keyboard focus and reordering. Check an internal page, mailto:, tel: and HTTPS links. Never store javascript: destinations. Add the blog archive to Navigation after creating the blog page: enabling the plugin does not decide its position in the menu. Test both a custom domain and a renderer URL with a site prefix.
Dropdowns, nested navigation and megamenus
Shared GS Loom menus support 5 levels, 30 siblings per branch and 100 items in total per menu. children contains items in the same format. menu_layout: "mega" lays out immediate children as columns; dropdown renders a list. Each item supports a library icon or image:<URL> selected/uploaded through the file manager.
Open Navigation in the builder, expand an item and use Add child item. Every level has a label, link, icon and submenu layout. Editing the site menu enables use_site_menu in GS Loom settings. Paylio uses the shared header; Skeleton and Victorie retain original demo navigation until this option is enabled, preserving existing websites during updates.
<gs-menu location="header" label="Menu"></gs-menu>{
"label": "Explore",
"href": "#",
"menu_layout": "mega",
"icon": "star",
"children": [{
"id": "services",
"label": "Services",
"href": "/services",
"icon": "globe",
"children": [{ "id": "design", "label": "Design", "href": "/design" }]
}]
}Submenus open on click or Enter/Space; Escape closes the current level and restores focus. When a parent has its own URL, that link appears first inside its panel, so opening a submenu does not navigate. On mobile, nested panels expand vertically. Theme tokens: --gs-menu-background, --gs-menu-color, --gs-menu-border, --gs-menu-radius, --gs-menu-gap; defaults inherit GS Loom/header tokens. Test long translations, touch, keyboard and desktop/tablet/mobile. Icons, URLs and layout remain language-independent.
Try the working dropdown and megamenu in GS Loom components.