# API Reference
# Plugin properties
TIP
VueMeta exports a Vue plugin as default export. This section describes the properties of that default export
# version
- type
string
The version of the plugin, it is the same as the package version
# install
The method used by Vue to install the plugin
# hasMetaInfo
- argument:
- vm (a Vue component)
- returns
boolean
A helper function which returns true when the Vue component passed as argument has metaInfo defined
# generate v2.2+
WARNING
This method is not available in the browser builds
- arguments:
- metaInfo
- options (optional)
- returns
metaInfo
This method is similar to $meta.inject()
but works without the need for a Vue instance
import VueMeta from 'vue-meta'
const { generate } = VueMeta
const rawMetaInfo = {
meta: [{ charset: 'utf-8' }]
}
const metaInfo = generate(rawMetaInfo /*, yourOptions*/)
const HEAD = metaInfo.script.text() + metaInfo.meta.text()
will result In
<meta charset="utf-8">
# Plugin options
# keyName
- type
string
- default
metaInfo
The name of the component option that contains all the information that gets converted to the various meta tags & attributes for the page
# attribute
- type
string
- default
data-vue-meta
The name of the attribute vue-meta arguments on elements to know which it should manage and which it should ignore.
# ssrAttribute
- type
string
- default
data-vue-meta-server-rendered
The name of the attribute that is added to the html
tag to inform vue-meta
that the server has already generated the meta tags for the initial render
See How to prevent update on page load
# ssrAppId
- type
string
- default
ssr
The app id for a server side rendered app. You shouldnt have to change this normally
# tagIDKeyName
- type
string
- default
vmid
The property that tells vue-meta
to overwrite (instead of append) an item in a tag list.
For example, if you have two meta
tag list items that both have vmid
of 'description',
then vue-meta will overwrite the shallowest one with the deepest one.
# contentKeyName
- type
string
- default
content
The key name for the content-holding property
# metaTemplateKeyName
- type
string
- default
template
The key name for possible meta templates
# refreshOnceOnNavigation runtime
- type
boolean
- default
false
When true
then vue-meta
will pause updates once page navigation starts and resumes updates when navigation finishes (resuming also triggers an update).
This could both be a performance improvement as a possible fix for 'flickering' when you are e.g. replacing stylesheets
TIP
Its not supported to disable refreshOnceOnNavigation
once enabled
# debounceWait v2.3+runtime
- type
number
- default
10
A timeout is used to debounce updates so vue-meta won't be updating the meta info immediately, this option determines how long updates are debounced
# waitOnDestroyed v2.3+runtime
- type
boolean
- default
true
Once a component is destroyed, vue-meta will update the meta information to make sure any info added by the destroyed component is removed.
To support transitions, vue-meta sets an interval to wait until the DOM element has been removed before it requests a meta info update. If you set this option to false
, the meta info update will be immediately called after nextTick
instead
# Plugin methods
The vue-meta
plugin injects a $meta()
function in the Vue prototype which provides the following methods
Note
$meta()
is a function so we only need to insert it once in the Vue.prototype
, but still use this
to reference the component it was called from
# $meta().getOptions
- returns
pluginOptions
Could be used by third-party libraries who wish to interact with vue-meta
# $meta().setOptions v2.3+
- arguments:
- options (type
object
)
- options (type
- returns
pluginOptions
You can toggle some plugin options during runtime by calling this method. Only plugin options marked runtime can be changed
vm.$meta().setOptions({ debounceWait: 50 })
# $meta().addApp v2.3+
- arguments:
- appName (type:
string
)
- appName (type:
- returns app object
{ set, remove }
Originally vue-meta
only supported adding meta info from Vue components. This caused some issues for third party integrations as they have to add their meta info through eg the root component while that already could contain meta info.
To improve this third party integrations can use addApp
to add their meta information.
Example of adding additional meta info for eg a third party plugin:
const { set, remove } = vm.$meta().addApp('custom')
set({
meta: [{ charset: 'utf=8' }]
})
setTimeout(() => remove(), 3000)
There is no reactivity for custom apps. The integrator need to take care of that and call set
and remove
when appropriate. If you call addApp.set
on the client before the app is mounted, the tags will be processed on the first refresh. If you call set when the app is mounted they tags are immediately processed.
The function is called addApp because the added metaInfo is treated exactly the same as when there are multiple apps on one page. Eg the tags that will be added will also list the appId
you specifiy:
<meta data-vue-meta="custom" charset="utf-8">
# $meta().refresh
- returns
metaInfo
Updates the current metadata with new metadata. Useful when updating metadata as the result of an asynchronous action that resolves after the initial render takes place.
# $meta().inject
- arguments
- injectOptions (type:
object
) v2.4+
- injectOptions (type:
- returns
metaInfo
SSR only
inject
is available in the server plugin only and is not available on the client
You can pass an object to inject with global inject options. See SSR injection method arguments for a list of available options.
It returns a special metaInfo
object where all keys have an object as value which contains a text()
method for returning html code
See Rendering with renderToString for an example
# Passing arguments to text()
In some cases you can pass an argument to the text method. E.g. to automatically add the ssrAttribute on ssr or render properties in the body
# $meta().pause
- arguments:
- refresh (type
boolean
, defaultfalse
)
- refresh (type
- returns
resume()
Pauses global metadata updates until either the returned resume method is called or resume
# $meta().resume
- arguments:
- refresh (type
boolean
, defaultfalse
)
- refresh (type
- returns
metaInfo
(optional)
Resumes metadata updates after they have been paused. If refresh
is true
it immediately initiates a metadata update by calling refresh
# metaInfo properties
Note
The documentation below uses metaInfo
as keyName
in the examples, please note that this is configurable and could be different in your case
# title
- type
string
Maps to the inner-text value of the <title>
element.
{
metaInfo: {
title: 'Foo Bar'
}
}
<title>Foo Bar</title>
# titleTemplate
- type
string | Function
The value of title
will be injected into the %s
placeholder in titleTemplate
before being rendered. The original title will be available on metaInfo.titleChunk
.
{
metaInfo: {
title: 'Foo Bar',
titleTemplate: '%s - Baz'
}
}
<title>Foo Bar - Baz</title>
The property can also be a function:
titleTemplate: (titleChunk) => {
// If undefined or blank then we don't need the hyphen
return titleChunk ? `${titleChunk} - Site Title` : 'Site Title';
}
# htmlAttrs
# headAttrs
# bodyAttrs
- type
object
Each key:value maps to the equivalent attribute:value of the <body>
element.
Since v2.0
value can also be an Array<string>
{
metaInfo: {
htmlAttrs: {
lang: 'en',
amp: true
},
bodyAttrs: {
class: ['dark-mode', 'mobile']
}
}
}
<html lang="en" amp>
<body class="dark-mode mobile">Foo Bar</body>
# base
- type
object
Maps to a newly-created <base>
element, where object properties map to attributes.
{
metaInfo: {
base: { target: '_blank', href: '/' }
}
}
<base target="_blank" href="/">
# meta
- type
collection
Each item in the array maps to a newly-created <meta>
element, where object properties map to attributes.
{
metaInfo: {
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
]
}
}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
# Content templates
Since v1.5.0
, you can now set up meta templates that work similar to the titleTemplate:
{
metaInfo: {
meta: [
{ charset: 'utf-8' },
{
property: 'og:title',
content: 'Test title',
// following template options are identical
// template: '%s - My page',
template: chunk => `${chunk} - My page`,
vmid: 'og:title'
}
]
}
}
<meta charset="utf-8">
<meta name="og:title" property="og:title" content="Test title - My page">
# link
- type
collection
Each item in the array maps to a newly-created <link>
element, where object properties map to attributes.
{
metaInfo: {
link: [
{ rel: 'stylesheet', href: '/css/index.css' },
{ rel: 'favicon', href: 'favicon.ico' }
]
}
}
<link rel="stylesheet" href="/css/index.css">
<link rel="favicon" href="favicon.ico">
# style
- type
object
Each item in the array maps to a newly-created <style>
element, where object properties map to attributes.
{
metaInfo: {
style: [
{ cssText: '.foo { color: red }', type: 'text/css' }
]
}
}
<style type="text/css">.foo { color: red }</style>
# script
- type
collection
Each item in the array maps to a newly-created <script>
element, where object properties map to attributes.
{
metaInfo: {
script: [
{ src: 'https://cdn.jsdelivr.net/npm/vue/dist/vue.js', async: true, defer: true }
],
}
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" async defer></script>
# Add JSON data v2.1+
If you wish to use a JSON variable within a script tag (e.g. for JSON-LD), you can directly pass your variable by using the json
property.
TIP
When passing an array or object to the json
property the keys and values of the variable will still be sanitized to prevent XSS
{
metaInfo: {
script: [{
type: 'application/ld+json',
json: {
'@context': 'http://schema.org',
unsafe: '<p>hello</p>'
}
}]
}
}
<script type="application/ld+json">
{ "@context": "http://schema.org", "unsafe": "<p>hello</p>" }
</script>
# Add other raw data
WARNING
You have to disable sanitizers so the content of innerHTML
won't be escaped. Please see __dangerouslyDisableSanitizersByTagID for more info on related risks
{
metaInfo: {
script: [{
vmid: 'ldjson-schema',
innerHTML: '{ "@context": "http://schema.org" }',
type: 'application/ld+json'
}],
__dangerouslyDisableSanitizersByTagID: {
'ldjson-schema': ['innerHTML']
},
}
}
<script type="application/ld+json">{ "@context": "http://schema.org" }</script>
# noscript
- type
collection
Each item in the array maps to a newly-created <noscript>
element, where object properties map to attributes.
{
metaInfo: {
noscript: [
{ innerHTML: 'This website requires JavaScript.' }
]
}
}
<noscript>This website requires JavaScript.</noscript>
# __dangerouslyDisableSanitizers
- type
Array<string>
WARNING
If you need to disable sanitation, please always use __dangerouslyDisableSanitizersByTagID when possible
By disabling sanitization, you are opening potential vectors for attacks such as SQL injection & Cross-Site Scripting (XSS). Be very careful to not compromise your application.
By default, vue-meta
sanitizes HTML entities in every property. You can disable this behaviour on a per-property basis using __dangerouslyDisableSanitizers
. Just pass it a list of properties you want sanitization to be disabled on:
{
metaInfo: {
title: '<I will be sanitized>',
meta: [{
vmid: 'description',
name: 'description',
content: '& I will not be <sanitized>'
}],
__dangerouslyDisableSanitizers: ['meta']
}
}
<title><I will be sanitized></title>
<meta vmid="description" name="description" content="& I will not be <sanitized>">
# __dangerouslyDisableSanitizersByTagID
- type
object
WARNING
By disabling sanitation, you are opening potential vectors for attacks such as SQL injection & Cross-Site Scripting (XSS). Be very careful to not compromise your application.
Provides same functionality as __dangerouslyDisableSanitizers
but you can specify which property for which tagIDKeyName
sanitation should be disabled. It expects an object with the vmid as key and an array with property keys as value:
{
metaInfo: {
title: '<I will be sanitized>',
meta: [{
vmid: 'description',
name: 'still-&-sanitized',
content: '& I will not be <sanitized>'
}],
__dangerouslyDisableSanitizersByTagID: {
description: ['content']
}
}
}
<title><I will be sanitized></title>
<meta vmid="description" name="still-&-sanitized" content="& I will not be <sanitized>">
# changed
- type
Function
A callback function which is called whenever the metaInfo
updates / changes.
The callback receives the following arguments:
- newInfo
- type
object
The updatedmetaInfo
object
- type
- addedTags
- type
Array<HTMLElement>
List of elements that were added
- type
- removedTags
- type
Array<HTMLElement>
List of elements that were removed
- type
{
metaInfo: {
changed (newInfo, addedTags, removedTags) {
console.log('Metadata was updated!')
}
}
}
# afterNavigation
- type
Function
A callback function which is called when vue-meta
has updated the metadata after navigation occurred.
This can be used to track page views with the updated document title etc.
Adding a afterNavigation
callback behaves the same as when refreshOnceOnNavigation is true
The callback receives the following arguments:
- newInfo
- type
object
The updatedmetaInfo
object
- type
{
metaInfo: {
afterNavigation(metaInfo) {
trackPageView(document.title)
// is the same as
trackPageView(metaInfo.title)
}
}
}
# Special metaInfo attributes
These attributes define specific features when used in a metaInfo property
# once
When adding a metaInfo property that should be added once without reactivity (thus will never be updated) you can add once: true
to the property.
once
only works reliably during SSR. When usingonce
in components, you need to also useskip
and store a skip status outside of the component scope.
{
metaInfo: {
link: [{
once: true,
rel: 'stylesheet'
href: 'style.css'
}]
}
}
or in combination with skip
let theJsHasBeenAddedSoSkipIt = false // <-- outside the component scope
export default {
...
head() {
const skip = theJsHasBeenAddedSoSkipIt
theJsHasBeenAddedSoSkipIt = true
return {
script: [
{ once: true, skip, src: '/file.js' }
]
}
}
}
# skip v2.1+
When a metaInfo property has a skip
attribute with truthy value it will not be rendered. This attribute helps with e.g. chaining scripts (see callback attribute)
{
metaInfo: {
script: [{
skip: true,
innerHTML: 'console.log("you wont see me")'
}]
}
}
# json v2.1+
The json
attribute in a metaInfo property allows you to render JSON content within a script tag, while still sanitizing the keys and values. For example this can be used to render JSON-LD.
{
metaInfo: {
script: [{
type: 'application/ld+json',
json: {
'@context': 'http://schema.org',
'@type': 'Organization',
name: 'NuxtJS'
}
}]
}
}
# body
# pbody v2.1+
WARNING
VueMeta supports the body and pbody attributes on all metaInfo properties, but its up to you or your framework to support these attributes during SSR
Using these body attributes without SSR support could result in hydration errors / re-rendering or missing tags.
You can filter tags to be included in the <body>
instead of the <head>
to e.g. force delayed execution of a script.
Use pbody: true
if you wish to prepend the tag to the body (so its rendered just after <body>
) or use body: true
to append the tag to the body (the tag is rendered just before </body>
).
{
metaInfo: {
script: [{
innerHTML: 'console.log("I am in body");',
type: 'text/javascript',
body: true
}]
}
}
# SSR Support
When rendering your template on SSR make sure to pass an object as first argument to the text method of the metaInfo property with either a value body: true
or pbody: true
<head>
<!-- render script tags in HEAD, no argument -->
${script.text()}
</head>
<body>
${script.text({ pbody: true })}
<div id="app"></div>
${script.text({ body: true })}
</body>
# callback v2.1+
vmid required on SSR
When using SSR it is required to define a vmid
property for the metaInfo property
The vmid is needed to resolve the corresponding callback for that element on hydration
The callback attribute should specify a function which is called once the corresponding tag has been loaded (i.e. the onload event is triggered). Use this to chain javascript if one depends on the other.
{
metaInfo() {
return {
script: [
{
vmid: 'extscript',
src: '/my-external-script.js',
callback: () => (this.externalLoaded = true)
},
{
skip: !this.externalLoaded,
innerHTML: `
/* this is only added once external script has been loaded */
/* and e.g. window.$externalVar exists */
`
}
]
}
},
data() {
return {
externalLoaded: false
}
}
}
# SSR injection methods
Calling inject
will return an object on which you can call the below methods to return the corresponding template string
# head v2.3+
- arguments
- ln (type
boolean
, default:false
)
- ln (type
This is a convenience method which will retrieve the template string which should be added to the head
.
Elements will be printed in the same order as the menu below.
By passing ln = true
a line break will be added after each element. This could be helpful e.g. during development to get a better overview of the tags added by vue-meta
# bodyPrepend v2.3+
- arguments
- ln (type
boolean
, default:false
)
- ln (type
This is a convenience method which will retrieve the template string which should be prepended to the body, i.e. listed just after <body>
.
Elements will be printed in the same order as the menu below.
# bodyAppend v2.3+
- arguments
- ln (type
boolean
, default:false
)
- ln (type
This is a convenience method which will retrieve the template string which should be appended to the body, i.e. listed just before </body>
.
Elements will be printed in the same order as the menu below.
# htmlAttrs.text
- arguments
- addSsrAttribute (type:
boolean
, default:false
)
- addSsrAttribute (type:
When addSsrAttribute: true
then the ssrAttribute
will be automatically added so you dont have to do that manually
# headAttrs.text
# bodyAttrs.text
See the SSR guide for more info on how to use this
# base.text
# meta.text
# link.text
# style.text
# script.text
# noscript.text
- arguments
- options (type:
object
, default:{ isSSR: true, ln: false , body: false, pbody: false }
)
- options (type:
Set isSSR: false
if you generate a SPA on server side and want to use the default appId 1
instead of ssrAppId
The body
and pbody
props can be used to support positioning of elements in your template, see SSR Support
By passing ln: true
a line break will be added after each element. This could be helpful e.g. during development to get a better overview of the tags added by vue-meta