Add the navigation

Beta

These docs rely on Slice Machine, which is in active development and subject to change. Content Relationships are not currently supported with Slices.

This article will introduce doing queries outside the Slice Zone and configuring custom types in Prismic. We'll show you how to handle the top navigation in your Prismic repository and Nuxt.js app.


See the navigation model

Looking at the top navigation, you can see that the model will be pretty simple. We don't know how many links we might need in the future, so we'll need to use a Group field to handle our links. Inside the Group field, we'll need:

  • A Link field to link to internal content
  • A Rich text field for the labels

Create a Menu Type and add content

For our Menu, we'll create one document which we'll query once and display everywhere. In the Custom Types section, create a single type Custom Type for the menu as we'll only be creating one version of the document. Call it 'Menu' with the API ID menu.

In the Menu Type's Static Zone add a Title field and a Group field. In the Group field, add a Link field and a Rich Text field. This will allow you to add as many links as you need.

You can see all the API IDs for these fields below:

Field

API ID

Title

title

Group

menu_links

Link

link

Rich Text

label

Then click 'Save to File System' + 'Push to Prismic' and jump over to the Prismic Dashboard. From here you can create a new Menu document and add your links and click 'Save' + 'Publish'.

You can see how your Menu Custom Type should look below:

The Menu Custom Type
The Menu Custom Type

Query the Menu content

Now heading back to the project code we're going to query the menu in the Vuex Store, call the query in the layout and create the menu component. All of which is explained in the Nav bars, footers and menus article, but we'll go over it again here.

Create your menu query

The best way to do this is to perform the getSingle query for your menu in the Vuex Store. This is run once when your project is initialised.

Copy
export const state = () => ({
  menu: {}
})

export const mutations = {
  SET_MENU(state, menu) {
    state.menu = menu
  },
  SET_ERROR(state, error) {
    state.menu = error
  }
}

export const actions = {
  async fetchMenu({ commit }, $prismic) {
    try {
      const menu = (await $prismic.api.getSingle('menu')).data

      commit('SET_MENU', menu)
    } catch (e) {
      const error = 'Please create a menu document'

      commit('SET_ERROR', error);
    }
  }
}

Call the query in the layout.

In the Nuxt app layout you can call the query to your Single type menu and then pass this data to your menu component, in this case, the menu is in a component called HeaderPrismic.

Copy
<template>
  <div class="homepage">
    <header-prismic/>
    <nuxt />
  </div>
</template>

<script>
import HeaderPrismic from '~/components/HeaderPrismic.vue'

export default {
  components: {
    HeaderPrismic
  },
  head () {
    return {
      title: 'Prismic Nuxt.js Multi Page Website',
    }
  },
  // Called before rendering the layout (even for error page)
  async middleware({ store, $prismic }) {
    await store.dispatch('fetchMenu', $prismic)
  }
}
</script>

Code and style menu component

Finally, in our component, we get the links and labels from the 'Store', loop through these and create our link with the nuxt-link component. Then we give it some nice styling.

See the full code below:

Copy
 <template>
  <header class="site-header">
    <p v-if="$store.state.menu === 'Please create a menu document'" class="logo">{{ $store.state.menu }}</p>
    <nuxt-link to="/" class="logo">{{ $prismic.asText($store.state.menu.title) }}</nuxt-link>
    <nav>
      <ul>
        <li v-for="menuLink in $store.state.menu.menu_links" :key="menuLink.id">
          <prismic-link :field="menuLink.link">{{ $prismic.asText(menuLink.label) }}</prismic-link>
        </li>
      </ul>
    </nav>
  </header>
</template>

<script>
export default {
  name: 'header-prismic',
}
</script>

<style scoped>
.site-header {
  height: 30px;
  padding: 20px 0;
  color: #484d52;
  font-weight: 700;
}
.site-header a {
  color: #484d52;
  font-weight: 700;
}
.site-header nav a:hover {
  color: #72767B;
}

.site-header .logo {
  display: inline-block;
  font-size: 22px;
  font-weight: 900;
}
.site-header nav {
  float: right;
}
.site-header nav ul {
  margin: 0;
  padding-left: 0;
}
.site-header nav li {
  display: inline-block;
  margin-left: 40px;
}

@media (max-width: 1060px) {
  .site-header {
    padding-left: 20px;
    padding-right: 20px;
  }
}
@media (max-width: 767px) {
  .site-header {
    height: auto;
  }

  .site-header {
    position: absolute;
    left: 0;
    right: 0;
  }

  .site-header .logo {
    display: block;
    text-align: center;
  }
  .site-header nav {
    float: none;
    text-align: center;
  }
  .site-header nav li {
    display: inline-block;
    margin-left: 10px;
    margin-right: 10px;
  }
}
</style>

See Your New Menu

Now all the hard work is done, simply run your project:

  • npm
  • Yarn
Copy
npm run dev
Copy
yarn dev

Boom! Simple as that you've got a website menu :)



Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Get in touch with us on our Community Forum.