Overview
A catalog menu is the primary navigation element that allows customers to browse the store by category. It is built from Lunar’s collection hierarchy: collection groups organize top-level navigation sections, and collections within each group form nested trees of categories and subcategories. This guide walks through querying collection groups and their nested collections, rendering a multi-level navigation menu, highlighting the active collection, and caching the result for performance. The examples below use standard Laravel controllers and Blade templates. The same concepts apply whether the storefront is built with Livewire, Inertia, or a headless API.How Collections Are Organized
Lunar organizes collections into a two-level structure:- Collection Groups act as top-level containers (e.g., “Main Menu”, “Footer Links”, “Seasonal Promotions”). Each group has a unique
handlefor identification. - Collections within a group form a nested tree using parent-child relationships. A root collection has no parent, and each root can have unlimited levels of children.
Main Menu (CollectionGroup)
Clothing
Men's
T-Shirts
Jackets
Women's
Dresses
Tops
Footwear
Sneakers
Boots
Accessories
Querying the Menu Data
Fetching a Collection Group
Retrieve a collection group by its handle. The handle is set when creating the group in the admin panel or via code.Fetching Root Collections
Root collections are those with no parent. Use the nested set’swhereIsRoot() scope to retrieve them.
defaultOrder() scope orders collections by their nested set position, which matches the order configured in the admin panel.
Fetching Children
Each collection’s children can be loaded via thechildren relationship. To build a full menu tree, eager load the children (and their children) to avoid N+1 queries.
children levels as needed for deeper menus.
Using descendantsOf for the Full Tree
For menus that need the entire tree regardless of depth, the nested set provides a descendantsOf method. However, for navigation menus it is generally better to eager load a fixed number of levels to keep queries predictable and avoid loading unnecessary data.
toTree() method on the resulting collection restructures the flat list into a nested tree, with each node’s children relation populated.
Building a Menu Service
Encapsulate the menu query in a dedicated service class to keep controllers clean and make caching straightforward.Rendering the Menu
Sharing Menu Data with All Views
Use a view composer or middleware to make the menu available to every page without passing it from each controller.When using a view composer with
'*', the menu query runs on every request. Pair this with caching (covered below) to avoid repeated database queries.Basic Menu Template
Recursive Menu for Unlimited Depth
For menus with an arbitrary number of levels, use a recursive Blade partial. Create a partial atresources/views/partials/menu-item.blade.php:
Active State Tracking
Highlighting the active collection (and its ancestors) helps customers understand where they are in the catalog hierarchy.Determining the Active Collection
In the collection controller, pass the current collection and its ancestor IDs to the view:Applying Active Styles
Share the active IDs with the layout so the menu partial can use them:Caching
The catalog menu changes infrequently compared to how often it is rendered. Caching prevents a database query on every page load.Cache the Menu Result
Update theCatalogMenuService to cache the menu:
Invalidating the Cache
Clear the cache whenever collections are updated. A model observer is a clean way to handle this:Multiple Menus
A store may need more than one navigation menu, for example a main header menu and a footer menu. Use separate collection groups for each.Channel and Customer Group Filtering
Collections support channel scheduling and customer group visibility. To display only collections available to the current browsing context, apply these scopes when building the menu.Putting It All Together
Here is a complete service, view composer, and Blade template for a cached, multi-level catalog menu:Service
View Composer
Blade Template
Next Steps
- Review the Collections reference for the full list of model fields, relationships, and sort options.
- Review the Product Listing Page guide for displaying products when a customer clicks a collection in the menu.
- Review the URLs reference for URL generation and slug management.
- Review the Channels reference for multi-channel configuration.