Navigation Menus

Learn how to create navigation menus in Next.js with Prismic.

Whether your website has thousands of pages or just one, it likely needs lists of links for navigation. This guide describes a simple and scalable way to manage navigation menus within Prismic.


The content models you’ll build throughout this guide support the following key features:

  • All navigation menus can be managed in Prismic. Content managers will be able to add, edit, and remove links from the menus.
  • Navigation menus can be reused in multiple contexts. A list of links displayed in the header, for example, could be reused in the footer with different styling.
  • Top-level links can contain child links when needed. Organizing pages under a parent is a common strategy to simplify top-level navigation menus.
  • Links can go anywhere. Content managers can link to whatever they need, both within the Prismic repository or out to other sites.

Content modeling

Two content models are needed:

  • A Navigation custom type
  • A Navigation Item slice

Create the Navigation Item slice

The reusable Navigation Item slice represents navigation links and their optional child links. It will be attached to the Navigation custom type.

Recreate the following Navigation Item in Slice Machine:

NavigationItemnavigation_itemSlice
  • Non-Repeatable Zone
    • LinklinkLink

      Link for the item

  • Repeatable Zone
    • Child Linkchild_linkLink

      Link for the child item

Create the Navigation custom type

The Navigation custom type represents collections of links, such as a website’s header or footer navigation. It uses the Navigation Item slice created above.

Recreate the following Navigation custom type in Slice Machine as a Reuseable custom type:

NavigationnavigationCustom Type
  • Static Zone
    • NamenameRich Text

      Name of the navigation list

    • UIDuidUID

      Unique ID for the navigation list

  • Slice Zone
    • NavigationItemSlice

Create a Navigation document

Open Prismic and create a Navigation Menu document with content.

Querying and Templating

Navigation documents can be queried in a Next.js layout file and called using the RootLayout function. This way, it’s only queried once and added to all the pages above or below the page content.

The data is queried within the <Navigation> component using the getByUID function. UPDATE THE UID TO MATCH YOURS. The navigation menu data returned from Prismic contains an array of slices holding your links.

The following <Navigation> component is one way to loop through each link and render it. You can customize the component by adding your own styling. It makes use of @prismicio/next’s <PrismicNextLink> component.

src/app/layout.js
import {
  PrismicNextLink,
  PrismicPreview,
} from "@prismicio/next";
import { createClient, repositoryName } from "@/prismicio";

export default async function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className="overflow-x-hidden antialiased">
        {/* @ts-expect-error Async Server Component */}
        <Navigation />
        {children}
        <PrismicPreview repositoryName={repositoryName} />
      </body>
    </html>
  );
}

async function Navigation() {
  const client = createClient();
  const navigation = await client.getByUID(
    "navigation",
    "header-menu",
  );

  return (
    <nav>
      <ul>
        {/* Renders top-level links */}
        {navigation.data.slices.map((slice) => (
          <li key={slice.id}>
            <PrismicNextLink field={slice.primary.link} />
            {/* Renders child links, if present */}
            {slice.items.length > 0 && (
              <ul>
                {slice.items.map((item) => (
                  <li key={JSON.stringify(item)}>
                    <PrismicNextLink
                      field={item.child_link}
                    />
                  </li>
                ))}
              </ul>
            )}
          </li>
        ))}
      </ul>
    </nav>
  );
}

Going further

The navigation strategy shared in this article can be used as-is or as a base for your own custom navigation strategy.

Here are a few ideas you can try to customize your navigation menus:

  • Allow content managers to select an icon for each link and display them in the menu.
  • Support short descriptions for top-level navigation items.
  • Automatically display an “external link” icon next to links pointing to external websites.
  • If you don’t need child links, remove the repeatable zone fields from the NavigationItem slice and remove its accompanying React code.
  • Learn more about querying in the Fetch Data article.
  • Learn more about templating content in the Template Content article.