Shopify app: widget.js waits up to 2 s for _sbp before injecting GTM

Hi, we use the Stape Conversion Tracking app on Shopify (candymovement.com) with “Insert GTM snippet” and Cookie Keeper, a Custom Loader on our own subdomain, and Cookiebot via the GTM CMP template (as recommended in #4087).

GTM, and with it the consent banner, only starts loading about 2.4 to 3 seconds after navigation.

We looked at the app embed (widget.js). Before it appends the GTM snippet, it waits for a Promise.all of:

  1. the settings request to /apps/widget/setting
  2. n(), which polls localStorage for _sbp every 200 ms and gives up after 2000 ms
  3. the Customer Privacy API check

Measurements (Chrome 156 on macOS, 4 page loads):

  • /apps/widget/setting completes in about 0.2 s.
  • _sbp is not in localStorage in this browser, so n() always runs into its 2 s timeout.
  • The GTM loader request starts 2.0 to 2.2 s after the Promise.all starts, on every load (746 → 2964 ms, 388 → 2391 ms, 416 → 2417 ms, 429 → 2432 ms).
  • In a second browser where _sbp is in localStorage, the loader starts after about 1.2 s.

So visitors without _sbp in localStorage get a fixed delay of about 2 seconds on every page view before GTM and the banner load. This may be related to the delay reported in #3645.

(Side note: earlier today we also saw the settings request itself take 6 to 11 s in one browser, but we could not reproduce it later.)

Questions:

  1. Is the 2 s wait intended? When is _sbp written to localStorage (e.g. only after consent, or only with Cookie Keeper)? Could the app skip or shorten the wait?
  2. In #1172 Dan mentioned the Custom Loader can be added directly to theme.liquid. If we do that and disable “Insert GTM snippet” in the app:
    • Does the checkout custom pixel (Data Layer tab code) keep working unchanged?
    • Do the storefront data layer events (view_item_stape etc.) keep working?
    • Which Cookie Keeper / user ID settings should the theme snippet use? The app’s snippet reads _sbp from a JS variable that widget.js sets, which wouldn’t exist yet if the snippet runs earlier in the head.

Thanks!

Hi @sweetrolls ,
As I understand it, if your main issue is that the consent banner takes too long to load, you can move to team.lequid not the entire GTM load, but specifically the script responsible for loading the consent banner. If that is the main problem, it will run first in terms of priority, rather than running after GTM loads, as it does now.

Regarding your specific questions:

Is the 2 s wait intended? When is _sbp written to localStorage (e.g. only after consent, or only with Cookie Keeper)? Could the app skip or shorten the wait?

I’m not sure about this, we’d need to check with the developers, but I doubt it’s possible to skip or shorten the delay.

  • In #1172 Dan mentioned the Custom Loader can be added directly to theme.liquid. If we do that and disable “Insert GTM snippet” in the app:

  • Does the checkout custom pixel (Data Layer tab code) keep working unchanged?

    The custom pixel operates independently of the GTM loading process via the app during checkout, so yes, it will continue to work.

  • Do the storefront data layer events (view_item_stape etc.) keep working?

    They will also continue to work, since the data layer functions operate independently of the GTM loading functions.

  • Which Cookie Keeper / user ID settings should the theme snippet use? The app’s snippet reads _sbp from a JS variable that widget.js sets, which wouldn’t exist yet if the snippet runs earlier in the head

If it loads before the variable is created, then that’s correct, it won’t work. That’s exactly why moving only the consent banner script is the best option.