Mega menu

I have a navigation menu similar to Prismic's navigation. Some navigation has a drop-down menu and some doesn't; see the image below.

How do I create it, and how do I fetch it with Nextjs 14? Thank you in advance!


There are many approaches you could take doing this. Actually, we have written a blog article on exactly how we did it for the Prismic website.

Here's how I would build it right now:

  • Create a single custom type called "Layout" with a tab named "Header".
  • Inside the "Header" tab's SliceZone, include a slice called "MenuItem" with two variations: "Default" (containing label and link fields) and "WithSubMenu" (containing label and a content relationship field linked to the "Sub Menu" custom type below). Alternatively, you could use a group field instead of slices here for simplicity.
  • Create a custom type called "Sub Menu" which includes tabs for sub menu columns, if needed. Within each tab, include a SliceZone with a "SubMenuItem" slice. This slice can have variations such as "Heading", "Link", "Button", "Separator", and so on.

In Next.js 14, the most common way to fetch it would be to have some kind of single document custom type, like a "layout" type explained above, which you fetch in your root layout file. Or even a header component, if it's a server component.

In our case, our header changes trough-out the site depending on page type, and we rely on some data from the pages in it, so we have a layout component on each page type, that takes data from the page to decide on how to render, this layout component fetches our single document with the menu items as well.

Tell me if something is unclear!

All the best

Hi Samuelhorn,

What about if some navigation parent doesn't have sub-navigation items? How do we build it?

Hi @solution.stack99 ,

I believe Samuel mentioned that above:

The "Default" variation is your navigation parent that doesn't have sub-navigation items.

1 Like

I followed that tutorial but I don't know how to fetch the data as there are three slices for this navigation.

In your Next.js page or layout component, you can fetch the layout data. You'll likely want to make this query in your layout component or in each page component, depending on your architecture.

Here's how you might fetch the layout data, including handling variations for menu items with and without sub-menus:

import { client } from '../prismicio';

export async function getLayoutData() {
  const layoutData = await client.getSingle('layout', {
    graphQuery: `{
      layout {
        header {
          menu_items {
            variation {
              ...on MenuItemDefault {
                link {
              ...on MenuItemWithSubMenu {
                sub_menu {
                  sub_menu_items {
, // Adjust according to your custom type's API ID and field

  return layoutData;

Step 3: Using the Data in Your Component

After fetching, you can pass the data to your layout or header component and render it accordingly. For example, if you're using server components in Next.js 14, you might pass the fetched layout data as props to your header component:

// In your page or layout component
const layoutData = await getLayoutData();

// Pass layoutData to your Header component
<Header layoutData={layoutData} />

Then, in your Header component, you would map over the layoutData to render your menu items and handle any sub-menus based on the structure of your Prismic documents.

Keep in mind that the exact implementation details will depend on your specific project setup, including how you've structured your custom types and documents in Prismic, and how you're handling state and props in your Next.js application. Adjust the field names and structure in the examples above according to your Prismic setup.

1 Like

Thank you, Phi! I will try it out.