Use Case: Menus
Learn how to create menus in Nuxt.
You’ll need to query the menu on every page, so we’ll show you the best practice for doing this below. This example is a fragment of our Multi-page sample project.
Model your menu in Prismic.
In this example, we have created a Single type custom type for the menu
as we will be creating one version of the document. We have a title field and a group field inside the menu
type.
In the group field, we added a link field and a rich text field; this way, you can add as many links as you need. Then, create a new menu document in your dashboard and add your content.
In your customtypes
folder, add a folder called menu
, then copy and paste this JSON into a file called index.json
(You’ll see it once you refresh Slice Machine):
{
"Main": {
"title": {
"type": "StructuredText",
"config": {
"placeholder": "Menu title...",
"single": "heading1"
}
},
"menu_links": {
"type": "Group",
"config": {
"fields": {
"label": {
"type": "StructuredText",
"config": {
"single": "paragraph",
"label": "Link Label",
"placeholder": "Link Label..."
}
},
"link": {
"type": "Link",
"config": {
"label": "Link",
"placeholder": "Select a Link..."
}
}
},
"label": "Menu Links"
}
}
}
}
Query the menu
The best way to do this is to perform the getSingle
query for your menu in the Vuex Store. The query runs when your project initializes.
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. The menu is in a component called ‘HeaderPrismic’ (We’ll create it in the next step).
<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>
Create a header
We can now access the data from the Vuex Store with $store
and implement it on the page.
<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>