change meta tags dynamically from index.html



  • hey everyone,
    I know this problem has been discussed before but I did not found a suitable solution
    I want to change some meta tags in a certain vue page for sharing on social media:
    i.e my index.html tags looks like this:

    <meta property=“twitter:card” content=“summary_large_image”>
    <meta property=“twitter:url” lang=“ar” content=“https://youhealthful.com”>
    <meta property=“twitter:title” lang=“ar” content=“YOUHEALTHFUL| Stay informed for COVID-19 updates and up to date health information.”>
    <meta property=“twitter:description” lang=“ar” content="">
    <meta property=“twitter:image” name=“twitter:image” content=“https://firebasestorage.googleapis.com/v0/b/youhealthful.appspot.com/o/shareableImages%2Ftwitter.png?alt=media&token=bb0dad3b-9e4f-4692-b03e-61c01221b1fc” >

    this meta tags are for the whole website
    in my article-view-page.vue I want to set twitter:image tag content to another url
    I tried quasar meta plugin but I cannot see any visible result so i used javascript in mounted (or created)
    document.querySelector(‘meta[property=“twitter:image”]’).setAttribute(“content”,this.article.image)
    and It really changed in the inspect partition in the head .
    the problem is my template part

    <ShareNetwork
    network=“twitter”
    :url=“youhealthful + title”
    :title=“title”
    description=“This article is about Covid 19”
    quote=""
    hashtags=“covid19,corona_virus”
    @open=“openTwitter”
    >
    <q-avatar size=“4vh” class=“q-mx-xl-sm q-mx-xs-xs cursor-pointer bg-blue-4 social-media-share”>
    <i class=“fab fa-twitter bg-blue-4 text-white” ></i>
    </q-avatar>
    </ShareNetwork>

    this component never sees the change in meta tag and always read the image in the index.html file
    does anyone have any suggestions ?



  • @ghada You will need to use SSR mode to change meta tags dynamically, and have scrapers like Twitter pick the changes up. It can be a bit of work to enable your app to run on the server, since things like document.querySelector won’t work there. The official meta plugin supports SSR. You can also roll your own, but it’s more work.



  • @ghada As @beets said. The reason for this is that those scrapers rarely run any javascript from pages you serve. So, dynamically just doesn’t make sense from the front-end side.



  • yeah, that could be a problem in typical spa/html pages but there is the way 🙂 without ssr also.
    If you are deploying bundled files on the www server with for example php, aspx or similar server side technology, then you can change your index.html into index.php and make any changes to headers dynamically as you wish.

    But that is not all. If you are using reverse proxy - let’s say nginx/openresty then you have a couple of other technologies at disposal. For example server side includes (ssi):

    http://nginx.org/en/docs/http/ngx_http_ssi_module.html

    Or with openresty - you have a full Lua programming language at the reverse proxy layer - for example something like this:

    https://openresty-reference.readthedocs.io/en/latest/Directives/

    with this directive:

    https://openresty-reference.readthedocs.io/en/latest/Directives/#body_filter_by_lua_block

    With those tools, you can change any fragment of body or headers from your pages, files, etc. before it is transmitted to the client browser.



  • @qyloxe I am using firebase with node js



  • @ghada said in change meta tags dynamically from index.html:

    @qyloxe I am using firebase with node js

    with node (express?) you have many templating engines:
    https://expressjs.com/en/resources/template-engines.html

    this one is quite nice as it is very similar to jinja2:

    https://mozilla.github.io/nunjucks/

    So in essence, your index.html from Quasar could be postprocessed by node/nunjucks based on request headers, context etc.



  • I followed this tutorial https://hackernoon.com/firebase-to-the-rescue-dynamic-routing-via-hosting-functions-integration-aef888ddf311
    and I put this snipit of code in the index.js in my backend folder.
    when I share through twitter for example It never shows the image in the index.html but also it never shares the image specified in this function although when I go to the link specified the tweet It shows the updated meta but a blank page!!!
    does this means I need to use firebase ssr???

    function buildHtmlWithArticle (article) {
    const string = ‘<!DOCTYPE html>\n’+
    ‘<html lang=“en” translate=“yes”> \n’+
    ‘<head> \n’+
    ‘<meta charset=“utf-8” /> \n’ +
    ‘<meta http-equiv=“X-UA-Compatible” content=“IE=edge” /> \n’+
    ‘<meta name=“viewport” content=“width=device-width,initial-scale=1.0” /> \n’ +
    ‘<meta http-equiv=“Content-Type” content=“text/html; charset=utf-8” /> \n’+
    ‘<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1” /> \n’+

    ‘<meta NAME=“geo.position” CONTENT=“latitude; longitude”> \n’+
    ‘<meta NAME=“geo.placename” CONTENT=“Place Name”> \n’+
    ‘<meta NAME=“geo.region” CONTENT=“Country Subdivision Code”></meta> \n’+
    ‘<meta http-equiv=“Cache-control” content=“public”> \n’+

    '<title>' + article.title + '</title>\n' + 
    '<meta property="og:title" content="' + article.title + '"> \n' +
    '<meta property="og:image" content="' + article.image + '"> \n' +
    '<meta property="twitter:title" content="' + article.title + '"> \n'+
    '<meta property="twitter:image" name="twitter:image"  content="' + article.image +'" > \n' +
    '</head> \n'+
    '<body> \n'+
    '<noscript> \n'+
      
    
    
    '<div id="app"></div> \n'+
    

    ‘</body> \n’+
    ‘</html>’

    return string;
    }
    exports.article = functions.https.onRequest( async (req, res) => {
    console.log(‘in article function’)
    console.log(‘path in req’,req.path)
    const path = req.path.split(’/’);
    console.log(‘path’,path)
    const articleId = path[2];

    const article = await admin
    .firestore()
    .doc(article/${articleId})
    .get()
    const item = Object.assign({}, article.data(), {
    id: article.uri,
    });
    const htmlString = buildHtmlWithArticle(item);
    console.log(‘html string’,htmlString)
    res.status(200).end(htmlString);

    });


Log in to reply