Best way to build a Mega menu #16007
-
|
I would love. amega menu on my website, and would love to control it from the backend. How would you do it? I put a nested array in global, an the website was not usable anymore (I waited a few minutes to open the page, once nothing happened I reverted back to the original file.
With only 3 nested levels was not usable: NOTE: I need more than 3 nested levels for my mega menu My current workaround: I moved the mega menu data to a static TypeScript file (src/Header/mega-menu.ts) and kept only simple fields in the Global (logo, clientAreaUrl, langFlag). The nav structure is hardcoded in TypeScript but typed and easy to edit (I don't like this solution at all though). Questions:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
The performance issue you're hitting is a known pain point with deeply nested arrays/blocks in Payload 3.x — it's not specific to SQLite, though SQLite makes it worse because of how Payload generates the join queries for nested structures. Here's the pattern I'd recommend for a mega menu: Use a separate collection instead of nesting everything in a Global. Create a const MenuItems: CollectionConfig = {
slug: 'menu-items',
admin: {
useAsTitle: 'label',
},
fields: [
{
name: 'label',
type: 'text',
required: true,
},
{
name: 'link',
type: 'text',
},
{
name: 'parent',
type: 'relationship',
relationTo: 'menu-items',
},
{
name: 'order',
type: 'number',
},
{
name: 'column',
type: 'number',
admin: {
description: 'Which column this item belongs to in the mega menu',
},
},
],
}Then in your Header global, use a simple relationship field: {
name: 'topLevelNav',
type: 'relationship',
relationTo: 'menu-items',
hasMany: true,
}On the frontend, fetch all menu items in a single query and build the tree in memory. This is way more performant than deeply nested blocks because:
To answer your specific questions:
|
Beta Was this translation helpful? Give feedback.
The performance issue you're hitting is a known pain point with deeply nested arrays/blocks in Payload 3.x — it's not specific to SQLite, though SQLite makes it worse because of how Payload generates the join queries for nested structures.
Here's the pattern I'd recommend for a mega menu:
Use a separate collection instead of nesting everything in a Global.
Create a
menu-itemscollection with a self-referencing relationship for hierarchy: