It seems that Vue Meta has been upgraded to handle Vue.js 3 with a new npm package called vue-3-meta
Before Vue.js 3, it was easy to use vue-meta
by adding it to the Vue instance:
import Vue from 'vue'
import VueMeta from 'vue-meta'
Vue.use(VueMeta, {
// optional pluginOptions
refreshOnceOnNavigation: true
})
However in Vue.js 3, there is no Vue instance; and instead you create the app by running createApp
like such:
const app = createApp(App);
const router = createVueRouter();
app.use(router);
// need to make app use Vue-Meta here
I cannot find any documentation for vue-3-meta
. import VueMeta from 'vue-meta'
no longer works.
How do I import the vue-3-meta
plugin properly and use it with app
like in prior versions?
The Vue 3.1 migration build is a “special” version of Vue 3 that allows your existing Vue 2 app to run in a Vue 2 mode (or Vue 2-compatible mode).
Buefy (8.7k stars on GitHub) integrates the CSS framework Bulma (43.7k stars on GitHub) into Vue. js 2 projects. However Buefy does not support Vue. js 3 yet.
Gridsome does not support Vue 3 yet. For more info refer to the kanban board for the Vue 3 upgrade on GitHub.
Before Vue.js 3, it was easy to use vue-meta by adding it to the Vue instance: import Vue from 'vue' import VueMeta from 'vue-meta' Vue.use (VueMeta, { // optional pluginOptions refreshOnceOnNavigation: true }) However in Vue.js 3, there is no Vue instance; and instead you create the app by running createApp like such:
For Vue.js apps, you need a plugin such as vue-metato add information to meta-tags in the <headtag. Alternatively, you could change your index.htmlfile and hard code static information in meta-tags that are displayed on every page of your app. But if you have a lot of urls, you really don’t want to do that from an SEO perspective.
A note on SSR and Pre-rendering Programmers who are using pre-rendering or server-side rendering (SSR) in their apps probably already use vue-meta, react-meta-tags or an alternative to add meta-tags for their app. For instance, vue-meta is officially used by Nuxt.js for Vue.js SSR.
Other metadata will be concatenated. vue-meta allows you to assign a special property called vmid to your metaInfo so that you can control how it resolves with your 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.
This was the minimal implementation I needed to get started:
Update vue-meta
to v3 (in package.json)
- "vue-meta": "^2.4.0",
+ "vue-meta": "^3.0.0-alpha.7",
...or with yarn:
yarn add vue-meta@alpha
Add metaManager
to Vue app
import { createMetaManager } from 'vue-meta'
const app = createApp(App)
.use(router)
.use(store)
.use(createMetaManager()) // add this line
await router.isReady()
app.mount('#app')
Add <metainfo>
to App.vue <template>
(this is also where I set a "title template")
<template>
<metainfo>
<template v-slot:title="{ content }">{{ content ? `${content} | SITE_NAME` : `SITE_NAME` }}</template>
</metainfo>
<header />
<router-view />
<footer />
</template>
Set default meta in App.vue <script>
Vue 3 vanilla:
import { useMeta } from 'vue-meta'
export default {
setup () {
useMeta({
title: '',
htmlAttrs: { lang: 'en', amp: true }
})
}
}
or with vue-class-component
:
import { setup, Vue } from 'vue-class-component'
import { useMeta } from 'vue-meta'
export default class App extends Vue {
meta = setup(() => useMeta({
title: '',
htmlAttrs: { lang: 'en', amp: true }
})
}
Override meta in each component
Vue 3 vanilla:
import { useMeta } from 'vue-meta'
export default {
setup () {
useMeta({ title: 'Some Page' })
}
}
or with vue-class-component
:
import { computed } from '@vue/runtime-core'
import { setup, Vue } from 'vue-class-component'
import { useMeta } from 'vue-meta'
export default class SomePage extends Vue {
meta = setup(() => useMeta(
computed(() => ({ title: this.something?.field ?? 'Default' })))
)
}
next
branch)next
branch)In addition to the previous answers, I also needed to add a transpileDependency
in my vue.config.js
, as I was using vue-cli
:
module.exports = {
transpileDependencies: ['vue-meta']
}
Else, I would get the error:
error in ./node_modules/vue-meta/dist/vue-meta.esm-browser.min.js
Module parse failed: Unexpected token (8:7170)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
Thanks to this thread for pointing me to this: https://stackoverflow.com/a/65844988/3433137
metaManager
is a MetaManager
instance created from createMetaManager()
of vue-meta
.
Based on the Vue 3 + Vue Router example for vue-meta
, here's an example usage:
import { createApp } from 'vue'
import { createMetaManager, defaultConfig, resolveOption, useMeta } from 'vue-meta'
const decisionMaker5000000 = resolveOption((prevValue, context) => {
const { uid = 0 } = context.vm || {}
if (!prevValue || prevValue < uid) {
return uid
}
})
const metaManager = createMetaManager({
...defaultConfig,
esi: {
group: true,
namespaced: true,
attributes: ['src', 'test', 'text']
}
}, decisionMaker5000000)
useMeta(
{
og: {
something: 'test'
}
},
metaManager
)
createApp(App).use(metaManager).mount('#app')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With