September 16, 2026
df7e36cefa61036cd05ebe4133b153030760eee4e978c43d583650ee21294a01 Previous:
e57eeaec Bundle: 95.9 KB The shopifyQL module gained new availability, readiness, context, and metric-tracking APIs.
Highlights
- Added api.shopifyQL.available() to asynchronously check whether the ShopifyQL API is present.
- Added api.shopifyQL.ready() which checks hasPermissions and falls back after a 30 second timeout.
- Added an internal getContext() method that throws an error if the ShopifyQL API is not available.
- Added trackMetricCard() to report metric card analytics events through the ShopifyQL API.
- Added a registerAnalyticsUiReady hook tied to a new internal ready promise for the ShopifyQL module.
Infrastructure Changes
REPORT.md +5 -5
@@ -1,6 +1,6 @@
# Shopify App Bridge — Unminification Report
Generated: 2026-09-15T08:03:57.378Z
Generated: 2026-09-16T08:04:17.824Z
## Files
@@ -8,7 +8,7 @@ Generated: 2026-09-15T08:03:57.378Z
|------|------|-------|------|
| _bootstrap.js | 30.1KB | 1051 | Infrastructure |
| _remote-ui.js | 6.1KB | 257 | Infrastructure |
| _utilities.js | 77.7KB | 2912 | Infrastructure |
| _utilities.js | 77.5KB | 2912 | Infrastructure |
| _web-vitals.js | 11.6KB | 527 | Infrastructure |
| analytics.js | 211B | 11 | Module |
| app.js | 346B | 15 | Module |
@@ -24,7 +24,7 @@ Generated: 2026-09-15T08:03:57.378Z
| picker.js | 451B | 18 | Module |
| polaris.js | 240B | 12 | Module |
| pos.js | 5.7KB | 248 | Module |
| print.js | 556B | 25 | Module |
| print.js | 545B | 25 | Module |
| resource-picker.js | 2.8KB | 117 | Module |
| reviews.js | 365B | 16 | Module |
| s-app-nav.js | 175B | 10 | Module |
@@ -33,7 +33,7 @@ Generated: 2026-09-15T08:03:57.378Z
| scanner.js | 2.9KB | 101 | Module |
| scopes.js | 797B | 26 | Module |
| share.js | 1.3KB | 58 | Module |
| shopifyQL.js | 262B | 12 | Module |
| shopifyQL.js | 1.2KB | 55 | Module |
| shortcut.js | 461B | 24 | Module |
| sidekick.js | 5.3KB | 179 | Module |
| support.js | 508B | 21 | Module |
@@ -46,7 +46,7 @@ Generated: 2026-09-15T08:03:57.378Z
| user.js | 940B | 37 | Module |
| visibility.js | 973B | 34 | Module |
| web-vitals.js | 1.9KB | 66 | Module |
| **Total** | **179.7KB** | **6832** | |
| **Total** | **180.4KB** | **6875** | |
## Pipeline Stages
modules/_bootstrap.js Truncated +4 -4
@@ -498,7 +498,7 @@
window.shopify = n.shopify;
window.polaris = n.polaris;
const t = window.open;
safeAsyncCall(self, 'open', function (n, e, i) {
Mt(self, 'open', function (n, e, i) {
return n != null && on(n).protocol !== 'https:'
? window.opener.open(n, e, i)
: t.call(this, n, e, i);
@@ -989,43 +989,43 @@
w.send('Loading.stop');
v.ready = Promise.resolve();
})();
var Re;
var xe;
var Oe;
var _e;
var Fe;
var Ue = -1;
var Ue;
var Be = function (t) {
var Be = -1;
var je = function (t) {
addEventListener(
'pageshow',
function (n) {
if (n.persisted) {
t(n);
}
},
true,
);
};
return (
window.performance &&
performance.getEntriesByType &&
performance.getEntriesByType('navigation')[0]
);
};
return (t && t.activationStart) || 0;
... (truncated)
Diff truncated at 200 lines
modules/_utilities.js Truncated +6 -6
@@ -200,18 +200,18 @@ function D() {
}
const N = Symbol();
const q = Symbol();
const V = Symbol();
const W = Symbol();
const H = Symbol();
const H = 'data-save-bar';
const V = 'data-save-bar';
const z = 'data-discard-confirmation';
const J = 'ui-save-bar';
const X = 'update';
const set = new Set();
for (const t of set) t.settle();
}
let i = false;
let o = null;
function r() {
@@ -602,14 +602,14 @@ function restoreProperty(t) {
}
}
}
function ORIGINAL_SYMBOL(t, n) {
function Tt(t, n) {
if (!{}.hasOwnProperty.call(t, n))
throw new TypeError('attempted to use private field on non-instance');
return t;
}
var Tt = 0;
var ORIGINAL_SYMBOL = 0;
function Lt(t) {
return `__private_${Tt++}_${t}`;
return `__private_${ORIGINAL_SYMBOL++}_${t}`;
}
function It(t = false) {
let n = null;
@@ -627,24 +627,24 @@ function It(t = false) {
writable: true,
value: new Set(),
});
ORIGINAL_SYMBOL(this, i)[i] = t;
Tt(this, i)[i] = t;
if (!((n = e) == null)) {
n.add(this);
}
}
... (truncated)
Diff truncated at 200 lines
modules/_web-vitals.js Truncated +0 -1
@@ -194,57 +194,57 @@ var ii = function (t, n) {
}),
);
};
passive: true,
capture: true,
};
}
};
var t = {
entryType: 'first-input' /* FID PerformanceObserver entry type */,
name: Re.type,
... (truncated)
Diff truncated at 200 lines
Module Changes
modules/fetch.js +1 -1
@@ -23,7 +23,7 @@ const deepClone = ({ api, protocol, internalApiPromise }) => {
verified: false,
};
}
safeAsyncCall(globalThis, 'fetch', async function (a, s) {
Mt(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/print.js +1 -1
@@ -4,8 +4,8 @@
*/
const printModule = ({ protocol, internalApiPromise }) => {
safeAsyncCall(self, 'print', function () {
Mt(self, 'print', function () {
const e = document.scrollingElement?.scrollHeight || document.body.offsetHeight;
Dt(async () => {
const { print: i } = (await internalApiPromise) || {};
modules/share.js +1 -1
@@ -4,9 +4,9 @@
*/
const shareModule = ({ protocol, internalApiPromise }) => {
const e = navigator.share;
safeAsyncCall(navigator, 'share', async function (i) {
Mt(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;
modules/shopifyQL.js +44 -1
@@ -7,5 +7,48 @@ const shopifyQLModule = ({ api, internalApiPromise }) => {
const e = Promise.resolve(internalApiPromise)
.then((t) => t?.shopifyQL ?? null)
.catch(() => null);
api.shopifyQL = Pe(e);
let i;
const promise = new Promise((t) => {
i = t;
});
promise.catch(() => {});
const r = Se(e);
const a = r.__internal;
r.__internal = a;
r.available = () => e.then((t) => t != null);
r.ready = async () => {
let t;
try {
return await Promise.race([
(async () => {
const t = await e;
if (!t) return Ee;
const n = await t.hasPermissions();
return n.isAvailable ? (await promise, n) : n;
})(),
new Promise((n) => {
t = setTimeout(() => {
n(Ee);
}, 3e4);
}),
]);
} catch {
return Ee;
} finally {
clearTimeout(t);
}
};
a.getContext = async () => {
const t = await e;
if (!t) throw Error('ShopifyQL API is not available');
return t.getContext();
};
a.registerAnalyticsUiReady = i;
a.trackMetricCard = async (t) => {
const n = await e;
if (n) {
await n.trackMetricCard(t);
}
};
api.shopifyQL = r;
};
modules/title-bar.js +2 -2
@@ -280,9 +280,9 @@ const titleBarModule = ({ protocol, internalApiPromise }) => {
const n = t[zn];
const e = t.getAttribute('label') ?? 'Actions';
const i = t.getAttribute('icon') || undefined;
const o = generateId(t.tagName, 's-menu')
const o = Yt(t.tagName, 's-menu')
? 'menu'
: generateId(t.tagName, 's-button-group')
: Yt(t.tagName, 's-button-group')
? 'inline'
: undefined;
return {
modules/ui-modal.js +1 -1
@@ -3,7 +3,7 @@
* Custom <ui-modal> element
*/
// Registry entry referenced as: Le
// Registry entry referenced as: Ie
modules/ui-nav-menu.js +1 -1
@@ -3,7 +3,7 @@
* Custom <ui-nav-menu> element
*/
// Registry entry referenced as: Ie
// Registry entry referenced as: $e