window.BOOMR throws an error

Tourist
5 0 5

Suddenly this appears in my code.

All my other stores wont have it.

 

(function () {
        if (window.BOOMR && (window.BOOMR.version || window.BOOMR.snippetExecuted)) {
          return;
        }
        window.BOOMR = window.BOOMR || {};
        window.BOOMR.snippetStart = new Date().getTime();
        window.BOOMR.snippetExecuted = true;
        window.BOOMR.snippetVersion = 12;
        window.BOOMR.url =
          "https://cdn.shopifycloud.com/boomerang/boomerang-latest.min.js" +
          "?shopId=9315188833&themeId=46009647201";
        var where = document.currentScript || document.getElementsByTagName("script")[0];
        var promoted = false;
        var LOADER_TIMEOUT = 3000;
        function promote() {
          if (promoted) {
            return;
          }
          var script = document.createElement("script");
          script.id = "boomr-scr-as";
          script.src=window.BOOMR.url;
          script.async = true;
          where.parentNode.appendChild(script);
          promoted = true;
        }
        function iframeLoader(wasFallback) {
          promoted = true;
          var dom, bootstrap, iframe, iframeStyle;
          var doc = document;
          var win = window;
          window.BOOMR.snippetMethod = wasFallback ? "if" : "i";
          bootstrap = function(parent, scriptId) {
            var script = doc.createElement("script");
            script.id = scriptId || "boomr-if-as";
            script.src=window.BOOMR.url;
            BOOMR_lstart = new Date().getTime();
            parent = parent || doc.body;
            parent.appendChild(script);
          };
          if (!window.addEventListener && window.attachEvent && navigator.userAgent.match(/MSIE [67]./)) {
            window.BOOMR.snippetMethod = "s";
            bootstrap(where.parentNode, "boomr-async");
            return;
          }
          iframe = document.createElement("IFRAME");
          iframe.src="about:blank";
          iframe.title = "";
          iframe.role = "presentation";
          iframe.loading = "eager";
          iframeStyle = (iframe.frameElement || iframe).style;
          iframeStyle.width = 0;
          iframeStyle.height = 0;
          iframeStyle.border = 0;
          iframeStyle.display = "none";
          where.parentNode.appendChild(iframe);
          try {
            win = iframe.contentWindow;
            doc = win.document.open();
          } catch (e) {
            dom = document.domain;
            iframe.src="x-javascript:var d=document.open();d.domain='" + dom + "';void(0);";
            win = iframe.contentWindow;
            doc = win.document.open();
          }
          if (dom) {
            doc._boomrl = function() {
              this.domain = dom;
              bootstrap();
            };
            doc.write("<body onload='document._boomrl();'><script id="__bs_script__">//<![CDATA[
    document.write("<script async src='/browser-sync/browser-sync-client.js?v=2.24.7'><\/script>".replace("HOST", location.hostname));
//]]></script>
");
          } else {
            win._boomrl = function() {
              bootstrap();
            };
            if (win.addEventListener) {
              win.addEventListener("load", win._boomrl, false);
            } else if (win.attachEvent) {
              win.attachEvent("onload", win._boomrl);
            }
          }
          doc.close();
        }
        var link = document.createElement("link");
        if (link.relList &&
          typeof link.relList.supports === "function" &&
          link.relList.supports("preload") &&
          ("as" in link)) {
          window.BOOMR.snippetMethod = "p";
          link.href = window.BOOMR.url;
          link.rel = "preload";
          link.as = "script";
          link.addEventListener("load", promote);
          link.addEventListener("error", function() {
            iframeLoader(true);
          });
          setTimeout(function() {
            if (!promoted) {
              iframeLoader(true);
            }
          }, LOADER_TIMEOUT);
          BOOMR_lstart = new Date().getTime();
          where.parentNode.appendChild(link);
        } else {
          iframeLoader(false);
        }
        function boomerangSaveLoadTime(e) {
          window.BOOMR_onload = (e && e.timeStamp) || new Date().getTime();
        }
        if (window.addEventListener) {
          window.addEventListener("load", boomerangSaveLoadTime, false);
        } else if (window.attachEvent) {
          window.attachEvent("onload", boomerangSaveLoadTime);
        }
        if (document.addEventListener) {
          document.addEventListener("onBoomerangLoaded", function(e) {
            e.detail.BOOMR.init({});
            e.detail.BOOMR.t_end = new Date().getTime();
          });
        } else if (document.attachEvent) {
          document.attachEvent("onpropertychange", function(e) {
            if (!e) e=event;
            if (e.propertyName === "onBoomerangLoaded") {
              e.detail.BOOMR.init({});
              e.detail.BOOMR.t_end = new Date().getTime();
            }
          });
        }
      })();
    

 

Problem: This does not work. Because of the comments the script ends apprupt.

doc.write("<body onload='document._boomrl();'><script id="__bs_script__">//<![CDATA[
    document.write("<script async src='/browser-sync/browser-sync-client.js?v=2.24.7'><\/script>".replace("HOST", location.hostname));
//]]></script>
");

 

Where does it come from?

{{ content_for_header }} ?

 

Thx,

F

0 Likes
Tourist
5 0 5

Working with Shopify Slate brings Browser Sync into the game.

I am not 100% sure, but I think Browser Sync adds its script at every occurrence of the »body« on the document.

In the Shopify {{ content_for_header }} Script is a document.write() with »body«:

 

doc.write("<body onload='document._boomrl();'>")

 

So Browser Sync will add its script after this and therefor breaks everything.

This only happens in Development-Mode.

Workaround is to remove the body from the 

{{ content_for_header }}

with

 

{{ content_for_header | replace: "<body onload='document._boomrl();'>", "<bodx onload='document._boomrl();'>" }}

 

 

I have no idea what this means in the context of boomr.

But its also not documented from the Shopify side... so... ?!

 

In case anybody stumbles upon the same problem,

F

3 Likes
Tourist
9 0 2

Great workaround, but seems like this needs to be fixed in the {{ content_for_header }} scripts by shopify, no? I would think browsersync is making a fair assumption in it's replacement regex searching for a body tag... 

 

I chose instead to 

  {% if request.host != 'yourstore.myshopify.com' %}
    {{ content_for_header }}
  {% endif %}

Since the site will have a different domain when it hit's production. 

1 Like
Highlighted
Tourist
5 0 5

Yes,

I definitely think it has to be fixed by Shopify. The assumption Browser Sync is making is more than fair. document.write() is not good practice at this point. They should select the document.body and add an onload event — dont they? I am not sure why they do it this way.

Your workaround seems better than mine; i didnt know that there is request object. Seems like a good way to separate dev and production. Thanks for sharing.

1 Like
Tourist
9 0 2

Update on this. The problem with my solution is it disables theme editing in the theme editor. (Although the upside is the tracking scripts don't run during development...)

 

However I just tried your solution and themekit complains that it's missing the {{content_for_header}} tag, so I'm now doing: 

  {% if false %}
    {{ content_for_header }}
  {% endif %}
  {{ content_for_header | replace: "<body onload='document._boomrl();'>", "<bodx onload='document._boomrl();'>" }}

 

0 Likes