Home > front end >  How to use Vue global variables in html head section?
How to use Vue global variables in html head section?

Time:07-23

I am using Vue version 2.6.11 in my website. I set some global variables according to this question in my src/main.js file as follow:

/* global variables */
Vue.prototype.$frontUrl = "http://localhost:8080/";
Vue.prototype.$backUrl = "http://localhost:3500/";

That works fine if I use them in my Vue views or components like this.$backUrl in this form tag:

<form novalidate  :action="this.$backUrl   'sql'" method="post"> 
<!-- some input tags ... -->
</form>

But I want to use them in my public/index.html file as the code below:

<!DOCTYPE html>
<html>
<head>

  <!-- og meta tags -->
    <meta name="type" property="og:type" content="website">
    <meta name="image" property="og:image" :content='this.$backUrl   "img/images/portfolio-preview.png"'>
    <meta name="url" property="og:url" content="">
    
</head>
</html>

It does not work. It does not give me any error but don't use Vue global variable value. If I see my page source in browsers, It shows me <meta name="image" property="og:image" :content='this.$backUrl "img/images/portfolio-preview.png"'>. Could anyone please help me how to use those variables in my index.html head section?

CodePudding user response:

This is a tricky question and I solved this way. All credit to this site who points the answer: link

create a definitions file definitions.js

export default {
  urlTest: "localhost:8080"
}

To keep code logic you need to change the global variables definitions for something like this:

import def from '../definitions.js'
Vue.prototype.$frontUrl = def.urlTest
//Only if you really need to store as a global

then on the vue-router where you define the path:

import HomeView from '../views/HomeView.vue'
import definitions from '../config/definitions.js'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [{
    path: '/',
    meta: {
      title: "Home",
      metaTags: [{
        //<meta name="image" property="og:image" :content='this.$backUrl   "img/images/portfolio-preview.png"'>
        name: 'image',
        property: 'og:image',
        content: definitions.urlTest   "/img/images/portfolio-preview.png"
      }]
    },
    name: 'home',
    component: HomeView
  }]
})

// This callback runs before every route change, including on page load.
router.beforeEach((to, from, next) => {
  // This goes through the matched routes from last to first, finding the closest route with a title.
  // e.g., if we have `/some/deep/nested/route` and `/some`, `/deep`, and `/nested` have titles,
  // `/nested`'s will be chosen.

  const nearestWithTitle = to.matched.slice().reverse().find(r => r.meta && r.meta.title);

  // Find the nearest route element with meta tags.
  const nearestWithMeta = to.matched.slice().reverse().find(r => r.meta && r.meta.metaTags);

  const previousNearestWithMeta = from.matched.slice().reverse().find(r => r.meta && r.meta.metaTags);
  // If a route with a title was found, set the document (page) title to that value.
  if (nearestWithTitle) {
    document.title = nearestWithTitle.meta.title;
  } else if (previousNearestWithMeta) {
    document.title = previousNearestWithMeta.meta.title;
  }

  // Remove any stale meta tags from the document using the key attribute we set below.
  Array.from(document.querySelectorAll('[data-vue-router-controlled]')).map(el => el.parentNode.removeChild(el));

  // Skip rendering meta tags if there are none.
  if (!nearestWithMeta) return next();

  // Turn the meta tag definitions into actual elements in the head.
  nearestWithMeta.meta.metaTags.map(tagDef => {
      const tag = document.createElement('meta');

      Object.keys(tagDef).forEach(key => {
        tag.setAttribute(key, tagDef[key]);
      });

      // We use this to track which meta tags we create so we don't interfere with other ones.
      tag.setAttribute('data-vue-router-controlled', '');

      return tag;
    })
    // Add the meta tags to the document head.
    .forEach(tag => document.head.appendChild(tag));

  next();
});

This is with Vue3 but with the method and router path definition has the same format. For more detailed explanation check the link on top.

CodePudding user response:

I finally found a solution with the help of Vue CLI Environment Variables. I saved my global variables values in a .env file in the root directory of project like the code below:

.env file:

VUE_APP_BACK_URL=http://localhost:3500/

Then I changed my src/main.js file that contains global variables like the code below:

main.js:

Vue.prototype.$backUrl = process.env.VUE_APP_BACK_URL;

So that I don't need to change other components and views that used this global variable. Finally for html head tag I used variables defined in .env file directly as could be seen in the code below:

<!DOCTYPE html>
<html>
  <head>
  
    <!-- og meta tags -->
    <meta name="type" property="og:type" content="website">
    <meta name="image" property="og:image" :content='<%= process.env.VUE_APP_BACK_URL   "img/images/portfolio-preview.png"%>'>
    <meta name="url" property="og:url" :content="<%= process.env.VUE_APP_BACK_URL %>">
  
  </head>
 </html>

  • Related