"Using the latest App Bridge script loaded from Shopify’s CDN" Failed

Hi everyone,

I’m developing an embedded Shopify app using Next.js and I’m failing one of the Embedded app checks. I can’t figure out what’s wrong.

Current status

:white_check_mark: Using session tokens for user authentication → passed
:cross_mark: Using the latest App Bridge script loaded from Shopify’s CDN → failed

The app loads correctly inside the iframe and works normally.


layout.tsx

This is what I render in my root layout:

...
<head>
  <meta
    name="shopify-api-key"
    content={process.env.NEXT_PUBLIC_SHOPIFY_API_KEY}
  />
  <script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"></script>
...
</head>
...

Frame source output

When I inspect the iframe source, both the meta tag and script are present:

...<meta name="shopify-api-key" content="xxx"/><meta name="application-name" content="xxx"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-status-bar-style" content="default"/><meta name="apple-mobile-web-app-title" content="xxx"/><meta name="mobile-web-app-capable" content="yes"/><meta name="theme-color" content="#000000"/><title>Dashboard | xxx</title><meta name="description" content="xxx Dashboard - Dashboard"/><link rel="author" href="https://xxx.co"/><meta name="author" content="xxx"/><link rel="manifest" href="/manifest.webmanifest"/><meta name="creator" content="xxx"/><meta name="publisher" content="xxx"/><meta name="robots" content="noindex, nofollow"/><link rel="canonical" href="https://xxx.co/dashboard"/><link rel="alternate" hrefLang="tr" href="https://xxx.co/dashboard"/><link rel="alternate" hrefLang="en" href="https://xxx.co/en/dashboard"/><meta name="format-detection" content="telephone=no, address=no, email=no"/><meta property="og:title" content="Dashboard"/><meta property="og:description" content="xxx Dashboard - Dashboard"/><meta property="og:url" content="https://xxx.co/dashboard"/><meta property="og:site_name" content="xxx"/><meta property="og:locale" content="xxx"/><meta property="og:image" content="https://xxx.co/og-image.png"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="Dashboard"/><meta property="og:locale:alternate" content="en_US"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Dashboard"/><meta name="twitter:description" content="xxx Dashboard - Dashboard"/><meta name="twitter:image" content="https://xxx.co/og-image.png"/><link rel="shortcut icon" href="/favicon.ico"/><link rel="icon" href="/favicon.ico" sizes="32x32"/><link rel="icon" href="/icon-16.png" sizes="16x16" type="image/png"/><link rel="icon" href="/icon-32.png" sizes="32x32" type="image/png"/><link rel="icon" href="/icon-48.png" sizes="48x48" type="image/png"/><link rel="icon" href="/icon-192.png" sizes="192x192" type="image/png"/><link rel="icon" href="/icon-512.png" sizes="512x512" type="image/png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" type="image/png"/><script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"></script>...

package.json

I intentionally do not install:

  • @shopify/app-bridge

  • @shopify/app-bridge-react

I’m using the CDN version according to Shopify documentation.


Environment

  • Next.js App Router

  • layout.tsx renders the head

  • app works inside iframe

  • session tokens pass validation

  • only the App Bridge CDN check fails


Question

Since the CDN script is clearly present in the rendered HTML, I don’t understand why Shopify’s check fails.

Has anyone experienced something similar?

Have you tried using curl to load your app home page to make sure that the app bridge script is SSR’d and not rendered on the client side?

That small detail might be causing the race condition.

Good catch — I tested this and confirmed something interesting.

Previously the route was redirecting to login, but I fixed the middleware so /dashboard/shopify always returns HTML and never redirects.

Now when I run:

curl -s x.com/dashboard/shopify

Note: My base App URL: x.com/dashboard/shopify

I get the full SSR HTML response, and it clearly contains both:

  • the shopify-api-key meta tag
  • the App Bridge CDN script

So the script is definitely server-rendered now, not client-injected.

However, even after this change — and after waiting quite a while for caches/checks to refresh — the Embedded App Check still fails with:

Using the latest App Bridge script loaded from Shopify’s CDN

So at this point:

:white_check_mark: SSR HTML contains the script
:white_check_mark: no redirect happens
:white_check_mark: curl confirms correct output
:cross_mark: Shopify check still reports failure

Does the checker expect the shopify-api-key meta tag and the App Bridge CDN script to be adjacent in the head (back-to-back), or in a specific order?

Right now they are both present in the initial HTML, but not necessarily next to each other. I’m wondering if the validator has stricter parsing requirements than documented.

Happy to provide more debugging info if needed.