Skip to content

Instantly share code, notes, and snippets.

@abidkhan484
Created May 15, 2026 10:12
Show Gist options
  • Select an option

  • Save abidkhan484/d441fe971a0b42cf9bdac8188a8adf2d to your computer and use it in GitHub Desktop.

Select an option

Save abidkhan484/d441fe971a0b42cf9bdac8188a8adf2d to your computer and use it in GitHub Desktop.

FlexibarEmbedStatus — How It Tracks Theme Embed Changes

The data source — shopify.app.extensions()

The component does not poll the theme or make any server calls. It reads from window.shopify.app.extensions() — a method injected by Shopify's App Bridge into the Admin iframe when AppProvider mounts in app/routes/app.jsx. App Bridge internally calls a Shopify Admin GraphQL API to retrieve the current embedded extension state for the shop.


When does it check?

Two triggers only:

1. On mount (initial render)

useEffect(() => {
  checkStatus();          // ← fires once when the component first mounts
  ...
}, [checkStatus]);

2. When the tab becomes visible again (visibilitychange)

const handleVisibilityChange = () => {
  if (document.visibilityState === "visible") {
    checkStatus();        // ← fires every time the Admin tab regains focus
  }
};
document.addEventListener("visibilitychange", handleVisibilityChange);

This is the key mechanism for picking up theme changes. The expected merchant flow is:

App Home (tab A)  →  Theme Editor (tab B, toggle embed)  →  switch back to tab A
                                                                       ↑
                                                          visibilitychange fires → checkStatus()

The component re-queries shopify.app.extensions() at that moment and reflects the new state.


What does checkStatus() actually do?

window.shopify.app.extensions()
        │
        ▼
 returns array of extension objects
        │
        ▼
 filter: looksLikeFlexibar(ext)          ← BFS over all fields + nested activations
         checks name/handle/type/id/uuid/key/target for "flexibar" or "inument-flexibar"
        │
        ▼
 any match? → hasTruthyStatus(ext)       ← BFS checks active/enabled/isActive/status=="active"
        │
        ├── true  → isEnabled = true  → Badge "Enabled" (green)
        ├── false → isEnabled = false → Badge "Disabled" (red)
        └── no extensions found       → isEnabled = false → "not found in this shop context"

What it does NOT do

Not implemented Why it matters
No polling / setInterval The badge won't update in real-time if the merchant toggles the embed without switching tabs
No WebSocket / push Changes in the theme editor on the same browser tab don't propagate until the merchant refocuses App Home
No server verification It trusts what App Bridge returns; if App Bridge isn't ready yet, it shows "API not available"

Practical implication

If a merchant toggles the Flexibar embed in the theme editor and returns to App Home in the same tab (e.g. via browser back button), visibilitychange fires and the badge updates automatically. If they never leave the App Home tab, they must press "Refresh status" manually to see the change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment