[Vuejs]-Error on creating a facebook like box component on vue

2👍

The template string problem

The presence if </script> inside the template string closes the tag (and the string), thus the “unterminated” error.

Fix: Escape the </script> by using <\/script>:

data: {
        fbSdk: `
  <div id="fb-root"></div>
  <script>
    (function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1";
    fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
  <\/script>
  `
    },

An alternative solution

Instead of adding the script, execute the code inside mounted() lifecycle hook.

First move the <div id="fb-root"></div> to the template. Second, have that logic go to the mounted, but make sure you add an if, so the <script> is not appended multiple times.

<template>
    <div>
        <div id="fb-root"></div>
        <div v-if="facebookPage" class="fb-page"
             :data-href="facebookPage"
             data-hide-cover="false"
             data-show-facepile="true"></div>
    </div>
    </div>
</template>

<script>
    export default{
        data: {},
        mounted() {
            if (!document.getElementById('facebook-jssdk')) {
                (function (d, s, id) {
                    var js, fjs = d.getElementsByTagName(s)[0];
                    if (d.getElementById(id)) return;
                    js = d.createElement(s);
                    js.id = id;
                    js.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1";
                    fjs.parentNode.insertBefore(js, fjs);
                }(document, 'script', 'facebook-jssdk'));
            }
        },
        computed: {
            facebookPage(){
                return (this.$store.getters.postLogin) ? this.$store.getters.postLogin.payload.facebook_page : null;
            },
        }
    }
</script>

A hack

Another alternative, is to use a sort of a vue hack to use <script> tag in the template. Basically you create a <vue-hack-script> component that will be rendered as <script> tag.

Example below:

<template>
  <div>
    <div id="fb-root"></div>
    <vue-hack-script v-once>
      (function (d, s, id) {
          var js, fjs = d.getElementsByTagName(s)[0];
          if (d.getElementById(id)) return;
          js = d.createElement(s);
          js.id = id;
          js.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1";
          fjs.parentNode.insertBefore(js, fjs);
      }(document, 'script', 'facebook-jssdk'));
    </vue-hack-script>
    
    <div v-if="facebookPage" class="fb-page"
         :data-href="facebookPage"
         data-hide-cover="false"
         data-show-facepile="true">
    </div>
  </div>
</template>

<script>
  export default {
    data: {},
    computed: {
      facebookPage() {
        return (this.$store.getters.postLogin) ? this.$store.getters.postLogin.payload.facebook_page : null;
      },
    },
    components: {
      'v-hack-script': { render: function (h) { return h('script', this.$slots.default) } }
    }
  }
</script>

Leave a comment