Meta plugin - dynamic properties



  • Hi,

    I’m trying to use meta plugin to dynamically inject description and title from components.
    For both of these there are additional meta tags that should get the same values:
    og:title, og:description, twitter:title, twitter:description
    I would like to define in the layout component that og:title (as example) should be the same as the title, and in the page component I just want to override the title itself.
    E.g.

    // MainLayout.vue
    <script>
    export default {
      meta () {
        return {
          title: ' My awesome site',
          meta: {
            ogTitle: { name:'og:title', content: this.meta.title }
          }
        }
      }
    }
    </script>
    
    // Page1.vue
    <script>
    export default {
      meta () {
        return {
          title: ' Page 1',
        }
      }
    }
    </script>
    

    This doesn’t work because this.meta is undefined while I’m still running meta() function.
    How can I make og:title tag match title tag that is defined on each page, without repeating its definition on each page?



  • The meta plugin will override the properties with the same name up the DOM heirarchy. You don’t need to do the overriding. You will however, need the meta method in each component defining the title. And, you’ll need to define in your components the data element (for reactivity/ dynamic values) of the meta prop. So:

    data () {
      return {
        title: 'some title'
      }
    }
    

    Scott



  • Thanks for the answer. But I think it’s not exactly what I’m looking for.
    In your solution I’d still have to define the meta tag og:title in each page, right?
    I.e

    meta () {
        return {
          title: this.title,
          meta: {
            ogTitle: { name:'og:title', content: this.title }
          }
        }
      }
    

    I was looking for a way that the pages will not have to define og:title at all.
    The reason is that there are many such social meta tags, and I don’t want to repeat their template on each page. og:title is just one example



  • @danbars said in Meta plugin - dynamic properties:

    I was looking for a way that the pages will not have to define og:title at all.
    The reason is that there are many such social meta tags, and I don’t want to repeat their template on each page. og:title is just one example

    maybe mixins will help you:

    https://vuejs.org/v2/guide/mixins.html

    … and router meta fields:

    https://router.vuejs.org/guide/advanced/meta.html



  • Or Vuex…

    Scott



  • @qyloxe @s-molinari - good ideas, thanks. I will check these directions.



  • Hi guys,

    I hope this post wont be considered a crosspost?

    Anyway this is how i have managed dynamic meta for my Quasar SSR site. This is regarding posts/news:

    In quasar.conf.js i have:

    // Quasar plugins
          plugins: ['Meta', 
    

    this is my scripts in the file that shows the single post:

    <script>
    import { mapGetters, mapState } from 'vuex'
    import { diFunctions } from 'src/mixins/general'
    export default {
      name: 'Post',
      mixins: [diFunctions],
      data () {
        return {
          imageStatic: process.env.API_URL + process.env.IMAGE_STATIC,
          imageUpload: process.env.API_URL + process.env.IMAGE_UPLOAD,
          imageMissing: process.env.IMAGE_MISSING,
          imageMissingDices: process.env.IMAGE_MISSING_DICES,
          post_type_2: process.env.POST_TYPE_2,
          post_type_3: process.env.POST_TYPE_3,
          post_type_4: process.env.POST_TYPE_4,
          post_type_5: process.env.POST_TYPE_5
        }
      },
      preFetch ({ store, currentRoute, previousRoute, redirect, ssrContext }) {
        if (!ssrContext) {
          const payload = { post_slug: currentRoute.params.post }
          return store.dispatch('posts/setPostObj', payload)
        }
      },
      computed: {
        ...mapState('posts', ['postObj', 'postMeta']),
        ...mapGetters('settings', ['getLocale'])
      },
      mounted () {
        if (process.browser) {
          this.doSetPostObj()
        }
      },
      methods: {
        async doSetPostObj () {
          try {
            const payload = { post_slug: this.$route.params.post }
            return this.$store.dispatch('posts/setPostObj', payload).then(() => {
              document.title = `${this.postMeta.title} - ${this.$t('general.appName')}`
            })
          } catch (error) {
            this.$router.replace('/error')
          }
        }
      },
      meta () {
        return this.setMeta(`${this.postMeta.title} - ${this.$t('general.appName')}`, this.postMeta.description, this.postMeta.ogUrl, this.postMeta.ogImage)
      }
    }
    </script>
    

    I use Vuex to set/get my meta:
    actions:

    export const setPostObj = async function (context, payload) {
      return await axiosInstance.get('api/site/getPostObj', {
        params: { post_slug: payload.post_slug }
      }).then(({ data }) => {
        context.commit('setPostObj', data)
        context.commit('setPostMeta', data)
      }).catch(err => {
        console.log(err)
      })
    }
    

    mutations:

    export const setPostMeta = (state, payload) => {
      state.postMeta.title = payload.postObj.title_sv
      state.postMeta.description = stripHtml(payload.postObj.content_sv).substr(0, 120)
      state.postMeta.ogUrl = process.env.APP_URL + 'nyhet/' + payload.postObj.post_slug
      state.postMeta.ogTitle = payload.postObj.title_sv
      state.postMeta.ogDesc = stripHtml(payload.postObj.content_sv).substr(0, 120)
      if (payload.postObj.products && payload.postObj.products.images[0]) {
        state.postMeta.ogImage = process.env.API_URL + process.env.IMAGE_UPLOAD + payload.postObj.products.images[0].image_file
      } else if (payload.postObj.prodsubcats && payload.postObj.prodsubcats.images[0]) {
        state.postMeta.ogImage = process.env.API_URL + process.env.IMAGE_UPLOAD + payload.postObj.prodsubcats.images[0].image_file
      } else if (payload.postObj.images[0]) {
        state.postMeta.ogImage = process.env.API_URL + process.env.IMAGE_UPLOAD + payload.postObj.images[0].image_file
      } else {
        state.postMeta.ogImage = process.env.IMAGE_MISSING_DICES
      }
      state.postMeta.twitterTitle = payload.postObj.title_sv
      state.postMeta.twitterDesc = stripHtml(payload.postObj.content_sv).substr(0, 120)
    }
    

    this used to work fine with corrrect result testin in https://metatags.io/ but now i get undefined and no image.

    Past this url https://www.hyreshuset.se/nyhet/glom-inte-boka-era-belysningsmaster into https://metatags.io and you’ll see.

    Any idea what i’m doing wrong? Maybe @s-molinari have some idea?



  • For anyone interested (as it may help), this is a new app extension: https://github.com/dreamonkey/quasar-app-extension-meta


Log in to reply