I'm using Nuxt.js to generate static pages. I want each page to have a unique <title>
tag and <meta property="og:title" ... >
tag.
I currently have an ugly solution that generates these tags. I have two pages that look like this:
pages/foo.vue
export default {
head: {
title: 'Foo',
meta: [
{
property: 'og:title',
content: 'Foo',
},
],
}
};
pages/bar.vue
export default {
head: {
title: 'Bar',
meta: [
{
property: 'og:title',
content: 'Bar',
},
],
}
};
This correctly generates <meta property="og:title" ...>
tags for each of my pages, but it forces me to include redundant code on all of my pages. My og:title
tag always matches my <title>
tag, so it makes no sense to redefine each of them independently on every page.
I'd love a solution that allows me to define the og:title
tag in my layouts/default.vue
file or even in nuxt.config.js
. Something like this:
layouts/default.vue
export default {
head() {
return {
meta: [
{
property: 'og:title',
content: this.$page.head.title, // <-- This variable doesn't really exist
}
],
};
},
};
pages/foo.vue
export default {
head: { title: 'Foo' }
};
pages/bar.vue
export default {
head: { title: 'Bar' }
};
Is is possible to eliminate the boilerplate here?
More generally, is it possible for Nuxt layouts to reference page-specific data?
A Layout.vue
cannot directly access to the nuxt data from a Page.vue
.
You have to use a Store
in order to share data between them.
See https://nuxtjs.org/guide/vuex-store/
About your initial request, you can use a Mixin
to share your meta configuration on each Page.vue
.
See https://v2.vuejs.org/v2/guide/mixins.html
eg.
// mixins/meta.vue
<script>
export default {
data () {
return {
title: null,
description: null
}
},
head () {
return {
title = this.title
meta = [
{ hid: 'description', name: 'description', content: this.description },
{ hid: 'og:title', property: 'og:title', content: this.title },
// ...
]
}
}
</script>
// <Page>.vue with local mixin
<script>
import Meta from '~/mixins/meta'
export default {
mixins: [Meta], // local mixin
asyncData () {
return {
title: "Foo",
description: "lorem ipsum",
}
}
}
</script>
or create a global mixin with a Nuxt plugin:
// plugins/meta.js
import Vue from 'vue'
Vue.mixin({
data: { // ... }
head: { // ...}
})
and declare your new plugin to apply on each Page:
// nuxt.config.js
plugins: ['~/plugins/meta'],