Use Case: Menus
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.
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"
}
}
}
}
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);
}
}
}
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>
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>
Was this article helpful?
Can't find what you're looking for? Spot an error in the documentation? Get in touch with us on our Community Forum or using the feedback form above.