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>
Can't find what you're looking for?
Need technical Support? Spot an error in the documentation? Get in touch with us on our Community Forum.