This content originally appeared on Alligator.io and was authored by Alligator.io
The vue-meta library provides a Vue plugin that allows us to take control of our app’s metadata from a component level. It’s important to curate the metadata of our web apps for SEO, but when working with single-page web applications (SPAs) this can often be a cumbersome task.
Dynamic metadata was already partially covered here, but our goal today is to highlight how the vue-meta plugin handles this for us in a concise, logical way while providing us with even more control over our app’s metadata.
Setup
Since vue-meta is a plugin we’ll need to add the package to our project dependencies. We’ll also need to let Vue know we want to use the vue-meta plugin.
Installation
Install vue-meta with your preferred package manager:
# Yarn
$ yarn add vue-meta
# NPM
$ npm install vue-meta --save
Bootstrap
Bootstrap the vue-meta plugin in your main
JavaScript file:
main.js
import Vue from 'vue';
import VueMeta from 'vue-meta';
import App from 'App.vue';
Vue.use(VueMeta);
new Vue({
el: '#app',
render: h => h(App)
});
If you’re using a routing solution like Vue Router, then you could bootstrap vue-meta in your router.js
file:
router.js
import Vue from 'vue';
import Router from 'vue-router';
import VueMeta from 'vue-meta';
Vue.use(Router);
Vue.use(VueMeta);
export default new Router({})
SSR
If you’re using Server Side Rendering you’ll want to bootstrap vue-meta in a file that runs on both the server and the client before the root Vue instance is mounted.
Vue Frameworks
If you’re using a framework that already uses vue-meta, such as NuxtJS, you won’t need to bootstrap. Instead, you should refer to the documentation for your chosen framework. Other frameworks that already use vue-meta include Gridsome, Ream, Vue-Storefront, and Factor.
Plugin Options
vue-meta provides options to customize the plugin’s behavior. NuxtJS takes advantage of this by changing the name of the metaInfo
property to head
. You could do this by bootstrapping vue-meta like so:
import Vue from 'vue';
import VueMeta from 'vue-meta';
import App from 'App.vue';
Vue.use(VueMeta, {
keyName: 'head'
});
new Vue({
el: '#app',
render: h => h(App)
});
Make sure to check out the full list of options available in the official documentation.
Populating Metadata
Titles
vue-meta allows us to update the <title>
tag on both parent and child components. In our root component we can define a default title that will appear if a child component lacks one. We can also define a titleTemplate
which will be used to display the title from child components.
App.vue
export default {
name: 'App',
metaInfo: {
title: 'Default App Title',
titleTemplate: '%s | vue-meta Example App'
},
...
}
<title>
Default App Title | vue-meta Example App
</title>
Other Metadata
Of course, title
isn’t the only thing we care about when populating a page’s metadata. Often we want to include other information to pass to the browser or web crawler such as a page’s charset
, description
, or viewport
. You can even add attributes to the page’s html
or head
tags and inject external scripts.
export default {
name: 'App',
metaInfo: {
title: 'Default App Title',
titleTemplate: '%s | vue-meta Example App',
htmlAttrs: {
reptilian: 'gator'
},
headAttrs: {
nest: 'eggs'
},
meta: [
{ charset: 'utf-8' },
{ name: 'description', content: 'gator' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
]
},
...
}
<html reptilian="gator">
<head nest="eggs">
<title>Default App Title | vue-meta Example App</title>
<meta charset="utf-8">
<meta name="description" content="gator">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
</html>
Make sure to check out the metaInfo properties spec of the vue-meta API documentation for all of the options available.
Component Metadata Hierarchy
Child components will recursively merge metadata with their parents. This allows us to update the page’s metadata based on which components are currently mounted.
App.vue
<template>
<div>
<HelloWorld />
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue';
export default {
name: 'App',
metaInfo: {
title: 'Default App Title',
titleTemplate: '%s | vue-meta Example App'
},
components: {
HelloWorld
}
}
</script>
HelloWorld.vue
<template>
<div>Hello World!</div>
</template>
<script>
export default {
name: 'HelloWorld',
metaInfo: {
title: 'Hello World!'
}
}
</script>
<title>
Hello World! | vue-meta Example App
</title>
You could also disable the titleTemplate
from a child component like so:
HelloWorld.vue
export default {
name: 'HelloWorld',
metaInfo: {
title: 'Hello World!',
titleTemplate: null
}
}
<title>
Hello World!
</title>
If two child components are mounted and both contain metaInfo
, the last child to be mounted will be used to populate the page’s metadata. Suppose we created a second child component called HelloWorld2
and modified our example as below:
Template: App.vue
<template>
<div>
<HelloWorld />
<HelloWorld2 />
</div>
</template>
Script: App.vue
import HelloWorld from './components/HelloWorld.vue';
import HelloWorld2 from './components/HelloWorld2.vue';
export default {
name: 'App',
metaInfo: {
title: 'Default App Title',
titleTemplate: '%s | vue-meta Example App'
},
components: {
HelloWorld,
HelloWorld2
}
}
HelloWorld2.vue
<template>
<div>Hello World 2!</div>
</template>
<script>
export default {
name: 'HelloWorld2',
metaInfo: {
title: 'Hello World 2!'
}
}
</script>
<title>
Hello World 2! | vue-meta Example App
</title>
Only duplicate metadata will be overwritten by child components. Other metadata will be concatenated.
Using multiple Vue instances with vue-meta will result in only the metadata from the last app to be updated!
VMID
vue-meta allows us to assign a special property called vmid
to our metaInfo
so that we can control how it resolves with our component tree. If two sets of metadata have the same vmid
, such as a parent and child, they will not merge but instead the child will override the parent like so:
// parent component
{
metaInfo: {
meta: [
{ charset: 'utf-8' },
{ vmid: 'description', name: 'description', content: 'reptilian' }
]
}
}
// child component
{
metaInfo: {
meta: [
{ vmid: 'description', name: 'description', content: 'gator' }
]
}
}
<meta charset="utf-8">
<meta data-vmid="description" name="description" content="gator">
Remove parent property in child
If a child component shares a vmid
with a parent and a metaInfo
property is set to null
, this property will be removed from the parent.
Conditional property in child
If a child component returns undefined
for a metaInfo
property vue-meta will fall back to the parent’s property.
Wrapping Up
vue-meta is a great solution if you’re looking to take control of and dynamically update your app’s metadata. It’s no question why so many popular Vue frameworks include the library out of the box. Make sure to take a look at the official documentation if you’d like to learn more about all the library has to offer.
This content originally appeared on Alligator.io and was authored by Alligator.io

Alligator.io | Sciencx (2020-03-06T00:00:00+00:00) Handling Metadata in Vue with vue-meta. Retrieved from https://www.scien.cx/2020/03/06/handling-metadata-in-vue-with-vue-meta/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.