Search code examples
javascriptvue.jsvuejs3vue-meta

How to use Vue 3 Meta with Vue.js 3?


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?


Solution

  • Disclaimer: vue-meta v3 is still in alpha!

    This was the minimal implementation I needed to get started:

    1. 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
      
    2. 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')
      
    3. 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>
      
    4. 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 }
        })
      }
      
    5. 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' })))
        )
      }
      

    See also: