App Bridge app navigation causes CLS during initial load

Hi Shopify team,

We investigated elevated CLS in our embedded React app and found a repeatable layout shift during App Bridge navigation initialization.

Observed behavior

During the initial load, the layout-shift attribution shows an element occupying the full iframe width with a height of 82.5px, then disappearing:

{
  "value": 0.06698950766747377,
  "sources": [
    {
      "previousRect": {
        "x": 0,
        "y": 0,
        "width": 1240,
        "height": 82.5
      },
      "currentRect": {
        "x": 0,
        "y": 0,
        "width": 0,
        "height": 0
      }
    }
  ]
}

This single shift contributes approximately 0.067 CLS.

What we tested

We reproduced the behavior with:

  • @shopify/app-bridge-react 4.1.6 using the legacy <NavMenu>
  • @shopify/app-bridge-react 4.2.13 using the current <s-app-nav> and <s-link> components

Upgrading and migrating the navigation did not remove the shift.

Is this temporary in-iframe layout expected during App Bridge initialization, or should App Bridge prevent the App Nav element from affecting the iframe layout before it is initialized?

This looks like a different mechanism than the known click-attribution CLS issue (web-vitals not excluding input from the parent iframe, Shopify/shopify-app-bridge#194), since yours fires on initial load rather than a nav click. Since it persists across both NavMenu and s-app-nav, it reads like App Bridge reserving space for the nav before it’s fully sized rather than anything in your app, I’d file it as feedback since there’s precedent for Shopify tracking App Bridge CLS issues.