Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercom ECMASCRIPT6 Tag Manager Error

I previously successfully setup intercom using Google Tag Manager. Haven't touched it for a couple of months and go to make a new tag but I'm presented with this error coming from the intercom tag:

Error at line 6, character 243: this language feature is only supported for ECMASCRIPT6 mode or better: block-scoped function declaration. Use --language_in=ECMASCRIPT6 or ECMASCRIPT6_STRICT or higher to enable ES6 features.

My script for intercom hasn't changed since it originally worked:

<script>
  window.intercomSettings = {
    app_id: "key"
  };
</script>
<script>(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/key';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()</script>

If anyone has encountered this error and has any advise or tips on how to solve it, it would be much appreciated.

like image 920
chdonncha Avatar asked Feb 13 '18 11:02

chdonncha


3 Answers

Before GTM wraps the code into a minimized JavaScript file to inject it into a page the code goes through a linter; the issue here is that Google sometimes changes the rules for the linter to make them more strict (this has popped up a few times on the GTM forum). Since this is not announced anywhere it occasionally breaks tags that have been working previously.

The problem here seems to be that you tag declare a function inside an if/else block. You can see this when you "beautify" your file:

<script>
    window.intercomSettings = {
        app_id: "key"
    };
</script>
<script>
    (function() {
        var w = window;
        var ic = w.Intercom;
        if (typeof ic === "function") {
            ic('reattach_activator');
            ic('update', intercomSettings);
        } else {
            var d = document;
            var i = function() {
                i.c(arguments)
            };
            i.q = [];
            i.c = function(args) {
                i.q.push(args)
            };
            w.Intercom = i;

            function l() {
                var s = d.createElement('script');
                s.type = 'text/javascript';
                s.async = true;
                s.src = 'https://widget.intercom.io/widget/key';
                var x = d.getElementsByTagName('script')[0];
                x.parentNode.insertBefore(s, x);
            }
            if (w.attachEvent) {
                w.attachEvent('onload', l);
            } else {
                w.addEventListener('load', l, false);
            }
        }
    })()
</script>

The "l" function is declared inside the "else" block and Google's linter does not like that (since previous versions of Javascript technically do not have a block scope for functions, this has only been introduced with ES6).

While I am certain that there is a correct way to fix this an easy way out would be to move the declaration of "l" outside the block:

<script>
    (function() {
        var w = window;

        function l() {
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://widget.intercom.io/widget/key';
            var x = d.getElementsByTagName('script')[0];
            x.parentNode.insertBefore(s, x);
        }
        var ic = w.Intercom;
        if (typeof ic === "function") {
            ic('reattach_activator');
            ic('update', intercomSettings);
        } else {
            var d = document;
            var i = function() {
                i.c(arguments)
            };
            i.q = [];
            i.c = function(args) {
                i.q.push(args)
            };
            w.Intercom = i;


            if (w.attachEvent) {
                w.attachEvent('onload', l);
            } else {
                w.addEventListener('load', l, false);
            }
        }
    })()
</script>

Does not look like it should have side effects and the tag works now (at least when I try it).

like image 140
Eike Pierstorff Avatar answered Oct 05 '22 09:10

Eike Pierstorff


Here is a full answer following the suggestion from @ruben-stolk. You also need to insert a semicolon at the end of the new function as in the snippet below. This was tested in GTM and passed the lint errors.

<script>
  window.intercomSettings = {
    app_id: "xe395ivj"
  };
</script>
<script>(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/xe395ivj';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()</script>
like image 40
Tony Abou-Assaleh Avatar answered Oct 05 '22 07:10

Tony Abou-Assaleh


What you can try to do is change your code from

function namedFunction(x) {}

to

var namedFunction = function(x){}
like image 45
Mary Vinitha Xavier Avatar answered Oct 05 '22 08:10

Mary Vinitha Xavier