All entries

June 17, 2026

cd7d0f3d0d3319fe3c0f1133fc57743d6d56a6f3ba557474e74be7258450b4e9
Previous: c3591477 Bundle: 90.4 KB

MobileBridgeNext safe area insets now inject styles via Constructable Stylesheets instead of a style element.

Highlights

  • MobileBridgeNext now injects safe area inset styles using the Constructable Stylesheets API and document.adoptedStyleSheets instead of appending a style element to document.head.
  • Safe area inset style injection now includes feature detection and exits gracefully if CSSStyleSheet or adoptedStyleSheets APIs are unavailable.
  • The function for intercepting native browser APIs was renamed from restoreProperty to interceptProperty, affecting the fetch, print, share, window.open, and history modules.
7 files changed +54 -39

Infrastructure Changes

REPORT.md
+4 -4
@@ -1,12 +1,12 @@
# Shopify App Bridge — Unminification Report

Generated: 2026-06-05T09:03:20.567Z
Generated: 2026-06-17T09:31:45.467Z

## Files

| File | Size | Lines | Type |
|------|------|-------|------|
| _bootstrap.js | 29.2KB | 1013 | Infrastructure |
| _bootstrap.js | 29.5KB | 1028 | Infrastructure |
| _remote-ui.js | 6.0KB | 255 | Infrastructure |
| _utilities.js | 72.9KB | 2721 | Infrastructure |
| _web-vitals.js | 11.6KB | 527 | Infrastructure |
@@ -24,7 +24,7 @@ Generated: 2026-06-05T09:03:20.567Z
| picker.js | 451B | 18 | Module |
| polaris.js | 240B | 12 | Module |
| pos.js | 5.7KB | 248 | Module |
| print.js | 573B | 25 | Module |
| print.js | 575B | 25 | Module |
| resource-picker.js | 2.8KB | 119 | Module |
| reviews.js | 365B | 16 | Module |
| s-app-nav.js | 175B | 10 | Module |
@@ -46,7 +46,7 @@ Generated: 2026-06-05T09:03:20.567Z
| user.js | 940B | 37 | Module |
| visibility.js | 973B | 34 | Module |
| web-vitals.js | 1.8KB | 64 | Module |
| **Total** | **171.9KB** | **6526** | |
| **Total** | **172.2KB** | **6541** | |

## Pipeline Stages


modules/_bootstrap.js
+27 -12
@@ -168,7 +168,7 @@
          removeEventListener: globalThis.removeEventListener.bind(globalThis),
          postMessage: globalThis.parent.postMessage.bind(globalThis.parent),
        });
  const c = Tt();
  const c = restoreProperty();
  const l = (function (t) {
    const n = t.decodeSignal;
    return (t) => {
@@ -467,18 +467,18 @@
      })(n.get('shopify-reload'));
    }
  }
    v.resolve(undefined);
    return void (async function () {
      const t = window.name.endsWith('/src');
      if (n) {
        window.opener = n;
        window.fetch = n.fetch;
        window.shopify = n.shopify;
        window.polaris = n.polaris;
        const t = window.open;
        restoreProperty(self, 'open', function (n, e, i) {
        interceptProperty(self, 'open', function (n, e, i) {
          return n != null && Dt(n).protocol !== 'https:'
            ? window.opener.open(n, e, i)
            : t.call(this, n, e, i);
@@ -934,20 +934,35 @@
  I(oe, t.disabledFeatures);
  (function (t) {
    if (!A('MobileBridgeNext')) return;
    const n = document.createElement('style');
    if (
    n.textContent =
      typeof CSSStyleSheet != 'function' ||
      "\n    :root { --shopify-safe-area-inset-bottom: 0px; }\n    body::after { content: ''; display: block; height: var(--shopify-safe-area-inset-bottom); }\n  ";
      typeof CSSStyleSheet.prototype.replaceSync != 'function' ||
    document.head.appendChild(n);
      !('adoptedStyleSheets' in Document.prototype)
    )
      return;
    let n;
    try {
      n = new CSSStyleSheet();
      n.replaceSync(
        ":root { --shopify-safe-area-inset-bottom: 0px; }\nbody::after { content: ''; display: block; height: var(--shopify-safe-area-inset-bottom); }",
      );
      document.adoptedStyleSheets = [...document.adoptedStyleSheets, n];
    } catch {
      return;
    }
    const e = n.cssRules[0];
    const i = (t) => {
      const n = Math.max(0, Math.floor(t || 0));
      e.style.setProperty('--shopify-safe-area-inset-bottom', n + 'px');
    };
    t.then((t) => {
      const n = t?.safeAreaInsets?.bottom;
      if (!n) return;
      if (n) {
      const e = (t) => {
        i(n.value ?? 0);
        document.documentElement.style.setProperty('--shopify-safe-area-inset-bottom', t + 'px');
        n.subscribe?.((t) => i(t));
      };
      }
      e(n.value ?? 0);
      n.subscribe?.((t) => e(t));
    });
  h.send('Loading.stop');
  y.ready = Promise.resolve();
})();

modules/_utilities.js Truncated
+19 -19
@@ -567,7 +567,7 @@ var createPrivateKey = 0;
function checkPrivateField(t) {
  return `__private_${createPrivateKey++}_${t}`;
}
function Tt(t = false) {
function restoreProperty(t = false) {
  let n = null;
  let e = t ? null : new Set();
  var i = checkPrivateField('value');
@@ -682,11 +682,11 @@ function Tt(t = false) {
    },
  };
}
Tt(true);
restoreProperty(true);
const interceptProperty = Symbol();
const Tt = Symbol();
function restoreProperty(t, n, e) {
function interceptProperty(t, n, e) {
  const i = t[n];
  e[interceptProperty] = i;
  e[Tt] = i;
  Object.defineProperty(t, n, {
    enumerable: true,
    configurable: true,
@@ -696,7 +696,7 @@ function restoreProperty(t, n, e) {
  return i;
}
function ORIGINAL_SYMBOL(t, n) {
  const e = t[n][interceptProperty];
  const e = t[n][Tt];
  if (e) {
    Object.defineProperty(t, n, {
      enumerable: true,
@@ -725,7 +725,7 @@ const Lt = ({ api, protocol, internalApiPromise }) => {
          verified: false,
        };
  }
  restoreProperty(globalThis, 'fetch', async function (a, s) {
  interceptProperty(globalThis, 'fetch', async function (a, s) {
    const request = new Request(a instanceof Request ? a.clone() : a, s);
    const { appOrigins: u = [] } = api.config;
    const url = new URL(request.url);
@@ -816,16 +816,16 @@ const It = ({ api, protocol, internalApiPromise }) => {
    return i;
  };
};
const deepClone = Symbol();
const Mt = Symbol();
class Mt {
class deepClone {
  constructor(t, n, e, i) {
    this.action = t;
    this.type = n;
    this.data = e;
    this[deepClone] = i;
    this[Mt] = i;
  }
  finish() {
    this[deepClone]();
    this[Mt]();
  }
}
class safeAsyncCall {
@@ -1017,7 +1017,7 @@ const zt = ({ internalApiPromise, saveBarManager, rpcEventTarget }) => {
    true,
  );
  const a = self.open;
  restoreProperty(self, 'open', function (t, e, i) {
  interceptProperty(self, 'open', function (t, e, i) {
    const o = t ? Dt(t).protocol : undefined;
    if (t == null || !o || !Ut.includes(o)) return a.call(this, t, e, i);
    if (saveBarManager.isSaveBarVisible) {
@@ -1095,16 +1095,16 @@ const zt = ({ internalApiPromise, saveBarManager, rpcEventTarget }) => {
      });
    }
  }
  restoreProperty(history, 'pushState', function (t, n, e) {
  interceptProperty(history, 'pushState', function (t, n, e) {
    c.call(history, t, n, e);
    s.pushState(e);
  });
  restoreProperty(history, 'replaceState', function (t, n, e) {
  interceptProperty(history, 'replaceState', function (t, n, e) {
    c.call(history, t, n, e);
    s.replaceState(e);
  });
  const d = HTMLFormElement.prototype.submit;
  restoreProperty(HTMLFormElement.prototype, 'submit', function () {
  interceptProperty(HTMLFormElement.prototype, 'submit', function () {
    saveBarManager.setFormSubmitting();
    d.call(this);
  });
@@ -1139,7 +1139,7 @@ const generateId = ({ protocol, internalApiPromise }) => {
  }
  if (i && 'navigate' in i) {
    i.navigate;
    const n = restoreProperty(i, 'navigate', function (e, i) {
    const n = interceptProperty(i, 'navigate', function (e, i) {
      const o = s(e);
      return o
        ? (protocol.send('Navigation.redirect.admin.path', {
@@ -1169,7 +1169,7 @@ const generateId = ({ protocol, internalApiPromise }) => {
    );
  else {
    const t = history.pushState;
    restoreProperty(history, 'pushState', function (n, e, i) {
    interceptProperty(history, 'pushState', function (n, e, i) {
      const r = location.href;
      t.call(this, n, e, i);
      if (i && new URL(i, r).href !== r) {
@@ -1180,7 +1180,7 @@ const generateId = ({ protocol, internalApiPromise }) => {
      ORIGINAL_SYMBOL(history, 'pushState');
    });
    const n = history.replaceState;
    restoreProperty(history, 'replaceState', function (t, e, i) {
    interceptProperty(history, 'replaceState', function (t, e, i) {
      const r = location.href;
      n.call(this, t, e, i);
      if (i && new URL(i, r).href !== r) {
@@ -1201,7 +1201,7 @@ const generateId = ({ protocol, internalApiPromise }) => {
    );
  }
  const r = self.open;
  restoreProperty(self, 'open', function (e, i, o) {
  interceptProperty(self, 'open', function (e, i, o) {
    if (e == null) return r.call(this, e, i, o);
    const a = (function (t) {
      const url = new URL(t, location.href);

Diff truncated at 200 lines

Module Changes

modules/fetch.js
+1 -1
@@ -23,7 +23,7 @@ const Lt = ({ api, protocol, internalApiPromise }) => {
          verified: false,
        };
  }
  restoreProperty(globalThis, 'fetch', async function (a, s) {
  interceptProperty(globalThis, 'fetch', async function (a, s) {
    const request = new Request(a instanceof Request ? a.clone() : a, s);
    const { appOrigins: u = [] } = api.config;
    const url = new URL(request.url);

modules/intents.js
+1 -1
@@ -44,7 +44,7 @@ const intentsModule = ({ api, protocol, internalApiPromise, signalFactory }) =>
        'AppFrame.propertiesEvent',
        ({ properties }) => {
          const o = (function (t, n, e) {
            return new Mt('configure', 'gid://flow/stepReference/' + t, n, () =>
            return new deepClone('configure', 'gid://flow/stepReference/' + t, n, () =>
              e.send('AppFrame.navigateBack'),
            );
          })(

modules/print.js
+1 -1
@@ -4,8 +4,8 @@
 */

const printModule = ({ protocol, internalApiPromise }) => {
    restoreProperty(self, 'print', function () {
    interceptProperty(self, 'print', function () {
      const e = document.scrollingElement?.scrollHeight || document.body.offsetHeight;
      SHOPIFY_PROTOCOLS(async () => {
        const { print: i } = (await internalApiPromise) || {};

modules/share.js
+1 -1
@@ -4,9 +4,9 @@
 */

const shareModule = ({ protocol, internalApiPromise }) => {
  const e = navigator.share;
  restoreProperty(navigator, 'share', async function (i) {
  interceptProperty(navigator, 'share', async function (i) {
    if (!i) return e.call(navigator, i);
    const { share: o } = (await internalApiPromise) || {};
    const { title: r, text: a, url: s } = i;