Skip to content

[Bug] Embedded app iframe blank on Vercel deployment — postMessage origin mismatch (template VERBATIM + Vercel = bug) #257

Description

@TODOLAB-WEB

Summary

After deploying the verbatim Shopify React Router app template to Vercel and installing it on a development store, the embedded app dashboard renders as a blank iframe in the Shopify admin. The browser console shows a postMessage target-origin mismatch between the iframe (hosted on *.vercel.app) and the recipient window (https://admin.shopify.com), which prevents App Bridge from completing initialization.

The issue is reproducible with the verbatim template (git clone of this repo, no modifications, no custom Vercel preset, no custom vercel.json) deployed to a fresh Vercel project with Vercel's auto-detected React Router framework preset.

A similar problem is reported in Shopify/shopify-app-js#3214 for a Fly.io host — same postMessage origin mismatch symptom. The pattern appears to be hosting-pattern-general, not specific to one provider.

Steps to reproduce

  1. git clone --depth=1 https://github.com/Shopify/shopify-app-template-react-router.git
  2. cd shopify-app-template-react-router && npm install
  3. Create a new Vercel project linked to this directory (Vercel auto-detects "React Router" framework — confirmed)
  4. Set required env vars on Vercel: SHOPIFY_API_KEY, SHOPIFY_API_SECRET, SCOPES, SHOPIFY_APP_URL, DATABASE_URL, DATABASE_URL_UNPOOLED (Postgres / Neon)
  5. vercel --prod → deploy succeeds, app reachable on https://<project>.vercel.app/
  6. In a Shopify Dev Dashboard app, set application_url to the Vercel URL and redirect_urls to <vercel_url>/auth/callback
  7. shopify app deploy --no-release && shopify app release --version=<v>
  8. Click "Install app" from the Dev Dashboard → OAuth flow completes successfully (token stored in Prisma Session table)
  9. From the Shopify admin of the dev store, open the installed app → iframe loads, then blank

Expected behavior

The iframe should render the Polaris placeholder page (web components from cdn.shopify.com/shopifycloud/polaris.js), as it does when the app is served from a Shopify-provided host such as shopify app dev (tunnel-based local dev).

Actual behavior

The iframe stays blank. Browser console shows:

common-XXXXXXX.js: Failed to execute 'postMessage' on 'DOMWindow':
  The target origin provided ('https://<project>.vercel.app')
  does not match the recipient window's origin ('https://admin.shopify.com').

VM app-bridge.js: Failed to fetch an idToken
  Error: idToken unavailable: host did not respond in time

cdn.shopify.com/shopifycloud/polaris.js was preloaded using link preload
  but not used within a few seconds from the window's load event.

App Bridge calls postMessage(msg, targetOrigin) against the parent admin window, but targetOrigin is set to the iframe's own origin (the Vercel app URL) instead of https://admin.shopify.com. The browser blocks the call for cross-origin safety. Downstream, the idToken request to the parent times out because the channel is never established.

Environment

  • Template: Shopify/shopify-app-template-react-router HEAD (cloned today, 2026-05-27)
  • @shopify/shopify-app-react-router: ^1.1.0
  • @shopify/app-bridge-react: tested both ^4.2.4 (current latest) and ^4.1.10 — same symptom
  • react-router: ^7.12.0
  • @react-router/dev: ^7.12.0
  • Vite: 6.4.2
  • Node.js (Vercel runtime): 24.x
  • Vercel CLI: 50.43.0 / 54.4.1 (both tested)
  • Region: tested both fra1 (Frankfurt) and iad1 (Washington DC) — same symptom

Things tried that did NOT fix the issue

  1. vercel.json rewrite ({ source: "/(.*)", destination: "/" } vs "/$1"): same error. Query params (host, embedded, hmac) confirmed arriving at the function via curl simulation.
  2. Downgrade @shopify/app-bridge-react from ^4.2.4 to ^4.1.10: same error.
  3. Remove @vercel/react-router preset and react-router.config.ts (when present): same error.
  4. Cross-platform fresh test (the conclusive one): cloned this template verbatim, fresh Vercel project, Vercel auto-detected React Router with zero-config, fresh deploy — same identical error with only the Vercel app subdomain changing in the target origin message.

Step 4 is the key evidence that the bug is in the template + Vercel combination, not in any modification on the developer side.

Cross-reference

Related: Shopify/shopify-app-js#3214 (Fly.io, same postMessage origin mismatch symptom). Suggests the bug is hosting-pattern-general.

Ask

  1. Is this a known issue?
  2. Is there a documented workaround in the meantime (e.g. a config option to set the App Bridge targetOrigin explicitly, or a meta tag the template should include but doesn't)?
  3. Is the React Router template officially supported on Vercel, or is there a hosting requirement (Shopify-provided host, Cloudflare Workers) documented somewhere that's not obvious?

Thanks for any pointer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions