Shopify/slate

Getting error with BrowserSync

josefarrugia opened this issue ยท 10 comments

I am currently using Shopify Slate to build a theme and I am now getting the following error printed out on my view:

"); } 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(); } }); } })(); if (!isDuplicatedThankYouPageView()) { setCookieIfThankYouPage(); window.ShopifyAnalytics.lib.page( null, {"pageType":"home"} ); } }); var eventsListenerScript = document.createElement('script'); eventsListenerScript.async = true; eventsListenerScript.src = "//cdn.shopify.com/s/assets/shop_events_listener-acf771159f9849ef6e5265782c99efe8b99406214c96a4373224ecafe285d7bb.js"; document.getElementsByTagName('head')[0].appendChild(eventsListenerScript); })();

Additionally, this is the line in question with the error:

doc.write("<script id="__bs_script__">//<![CDATA[

I am not the only one experiencing this issue as found here on the Shopify developer forums here.

Any thoughts or ideas? Let me know if I missed anything out!

Getting this same error. I wonder if it has anything to do with my setting because I am only getting it in 1 of 2 themes I am developing.

@michaelburtonray it's something to do with Shopify updating their analytics scripts as they are placing a <body> tag within the script tags, thus, BrowserSync is attaching itself to the wrong body tag.

Here's my current fix which in effect places the BrowserSync injection just before the closing </body> tag

snippetOptions: {
    rule: {
        match: /<\/body>/i,
        fn: function (snippet, match) {
            return snippet + match;
        }
    }
}

Perhaps I should do a pull request and add the above snippet in the dev-server of slate-tools?

Received this same error today out of the blue on one of my repos.

@josefarrugia How can I switch to dev-server of slate-tools? I tried choosing the version manually as a @shopify/slate-tools development dependency, but it was not listed.

Should I set the snippetOptions in my own repo? If so, could you please provide me with some instructions, as I understand browsersync is part of slate-tools and I would like to keep the footprint as minimal as possible.

Thank you

Thanks @josefarrugia ! Where does that code go? I tried putting it in slate.config.js and it didn't change anything.

@peeppirnpuu if you want to keep the footprints and work minimal try moving {{ content_for_header }} into <body> instead of <head> this should be a work around while you develop the solution and it will be shared with the people you work with on that theme if you're using git where the other solution might not

Just remember to move it back into <head> before you release it

Thanks @josefarrugia ! Where does that code go? I tried putting it in slate.config.js and it didn't change anything.

@michaelburtonray This should be included in the recently released beta19.

In the case where you need to manually modify, you have to make the change directly to @shopify/slate-tools/tools/dev-server/index.js file in your node_modules.

To fix, change the below within node_modules/@shopify/slate-tools/tools/dev-server/index.js

Before

const browserSync = require('browser-sync');
const {getStoreValue, getThemeIdValue} = require('@shopify/slate-env');
const {getSSLKeyPath, getSSLCertPath} = require('../utilities');

class DevServer {
  constructor(options) {
    this.bs = browserSync.create();
    this.target = `https://${getStoreValue()}`;
    this.themeId = getThemeIdValue();
    this.port = options.port;
    this.address = options.address;
    this.uiPort = options.uiPort;
    this.proxyTarget =
      this.target +
      (this.themeId === 'live' ? '' : `?preview_theme_id=${this.themeId}`);
  }
  start() {
    const bsConfig = {
      port: this.port,
      proxy: {
        target: this.proxyTarget,
        middleware: (req, res, next) => {
          // Shopify sites with redirection enabled for custom domains force redirection
          // to that domain. `?_fd=0` prevents that forwarding.
          // ?pb=0 hides the Shopify preview bar
          const prefix = req.url.indexOf('?') > -1 ? '&' : '?';
          const queryStringComponents = ['_fd=0&pb=0'];

          req.url += prefix + queryStringComponents.join('&');
          next();
        },
      },
      https: {key: getSSLKeyPath(), cert: getSSLCertPath()},
      logLevel: 'silent',
      socket: {
        domain: `https://${this.address}:${this.port}`,
      },
      ui: {
        port: this.uiPort,
      },
    };

    return new Promise((resolve) => {
      this.server = this.bs.init(bsConfig, resolve);
    });
  }
}

module.exports = DevServer;

After


const browserSync = require('browser-sync');
const {getStoreValue, getThemeIdValue} = require('@shopify/slate-env');
const {getSSLKeyPath, getSSLCertPath} = require('../utilities');

class DevServer {
  constructor(options) {
    this.bs = browserSync.create();
    this.target = `https://${getStoreValue()}`;
    this.themeId = getThemeIdValue();
    this.port = options.port;
    this.address = options.address;
    this.uiPort = options.uiPort;
    this.proxyTarget =
      this.target +
      (this.themeId === 'live' ? '' : `?preview_theme_id=${this.themeId}`);
  }
  start() {
    const bsConfig = {
      port: this.port,
      proxy: {
        target: this.proxyTarget,
        middleware: (req, res, next) => {
          // Shopify sites with redirection enabled for custom domains force redirection
          // to that domain. `?_fd=0` prevents that forwarding.
          // ?pb=0 hides the Shopify preview bar
          const prefix = req.url.indexOf('?') > -1 ? '&' : '?';
          const queryStringComponents = ['_fd=0&pb=0'];

          req.url += prefix + queryStringComponents.join('&');
          next();
        },
      },
    // Fix analytics injection bug
      snippetOptions: {
        rule: {
            match: /<\/body>/i,
            fn: function (snippet, match) {
                return snippet + match;
            }
        }
    },
      https: {key: getSSLKeyPath(), cert: getSSLCertPath()},
      logLevel: 'silent',
      socket: {
        domain: `https://${this.address}:${this.port}`,
      },
      ui: {
        port: this.uiPort,
      },
    };

    return new Promise((resolve) => {
      this.server = this.bs.init(bsConfig, resolve);
    });
  }
}

module.exports = DevServer;

666

If someone is not using slate, but browser-sync from command line, it can put this code into default configuration which can be generated with browser-sync init.

browser-sync init
# this will generate file: bs-config.js
# add snippetOptions attribute to that configuration

Now you can start browser sync with shopify theme with

browser-sync start --proxy "https://<mystore>.myshopify.com/" --files "*/*.*" --reload-delay 1000 --config bs-config.js