We have an embedded Polaris app that includes a Shopify-style search + filter bar (modeled on the bar found on admin.shopify.com/.../products and .../inventory). The bar is meant to switch between a “comfortable” desktop layout (28px tall, 13px text) and a “compact” mobile layout (40px tall, 16px text) at Polaris’s standard 30.625em / 490px breakpoint, matching the first-party admin behaviour.
The problem: from inside an embedded app’s iframe, neither @media queries nor @container queries reflect the merchant’s actual browser viewport -they only see the iframe’s own width, which is dictated by Shopify’s admin chrome.
Concretely, as a merchant resizes their browser, the iframe width changes in a non-monotonic way because the admin’s nav sidebar collapses at some point. Here are six scenarios I observed, comparing the first-party admin bar (still comfortable) against our embedded bar (which uses a 490px container query):
- Browser at 1400px, admin sidebar shown, iframe ≈1100px. First-party: comfortable. Embedded: comfortable.
- Browser at 800px, admin sidebar shown, iframe ≈500px. First-party: comfortable. Embedded: comfortable (just barely).
- Browser at 700px, admin sidebar shown, iframe ≈400px. First-party: comfortable. Embedded: COMPACT - mismatch starts.
- Browser drops to ≈1023px, admin sidebar collapses, iframe expands to ≈1023px. First-party: comfortable. Embedded: comfortable (jumps back).
- Browser at 500px, sidebar collapsed, iframe ≈500px. First-party: comfortable. Embedded: comfortable.
- Browser at 480px, sidebar collapsed, iframe ≈480px. First-party: compact. Embedded: compact.
So our embedded bar zigzags between compact and comfortable across a resize that should leave it stable, because we’re measuring the iframe and the first-party bar is measuring the browser viewport.
What I’ve checked
shopify.environment- exposesembedded`,intent,mobile,pos.mobileis documented as “running inside Shopify Mobile” (the native app), not “narrow desktop viewport”. Noviewport/layout/screenproperties.- App Bridge APIs index ( App Bridge APIs and web methods ) - Authentication and Data / UI and Interactions / Device and Platform Integration. Nothing exposes admin viewport, sidebar state, or breakpoint signals.
s-query-container- wraps standard CSS container queries; measurement is iframe-bound.window.parent.innerWidth- blocked cross-origin.postMessagehandshake - admin doesn’t broadcast viewport info to embedded apps by default.--shopify-safe-area-inset-bottom- auto-injected on Shopify Mobile for the bottom nav. Doesn’t fire for desktop sidebar.screen.width`/screen.availWidth`- usable as a “what monitor is this” floor, but doesn’t reflect browser-window resizes.navigator.maxTouchPoints/(hover: hover)- useful for touch detection, but orthogonal to “is the admin sidebar shown”.
Questions
- Is there an existing App Bridge API or convention I missed for reading the merchant’s actual browser viewport, or for being notified when Shopify’s admin sidebar collapses/expands?
- If not, what’s the recommended approach for an embedded app that wants to match the first-party admin’s responsive breakpoints exactly (so e.g. a Shopify-style search bar inside an app’s iframe responds at the same width as Shopify’s own bar)?
- Would Shopify consider exposing a
shopify.viewport(or similar) read-only property + change event onshopify, or a CSS custom property keyed to admin breakpoints, so embedded apps can stay in step with admin chrome state?
Thanks!