How can an embedded app detect the merchant's browser viewport (not the iframe width)?

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 - exposes embedded`, intent, mobile, pos. mobile is documented as “running inside Shopify Mobile” (the native app), not “narrow desktop viewport”. No viewport / layout / screen properties.
  • 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.
  • postMessage handshake - 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

  1. 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?
  2. 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)?
  3. Would Shopify consider exposing a shopify.viewport (or similar) read-only property + change event on shopify, or a CSS custom property keyed to admin breakpoints, so embedded apps can stay in step with admin chrome state?

Thanks!

I was thinking about adding a bar like that to my app, but I thought would just make everything look more complex.

I’ve tried adding the curve that Shopify has in the darkbackground, but it also didnt lookt as nice.