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
git clone --depth=1 https://github.com/Shopify/shopify-app-template-react-router.git
cd shopify-app-template-react-router && npm install
- Create a new Vercel project linked to this directory (Vercel auto-detects "React Router" framework — confirmed)
- Set required env vars on Vercel:
SHOPIFY_API_KEY, SHOPIFY_API_SECRET, SCOPES, SHOPIFY_APP_URL, DATABASE_URL, DATABASE_URL_UNPOOLED (Postgres / Neon)
vercel --prod → deploy succeeds, app reachable on https://<project>.vercel.app/
- In a Shopify Dev Dashboard app, set
application_url to the Vercel URL and redirect_urls to <vercel_url>/auth/callback
shopify app deploy --no-release && shopify app release --version=<v>
- Click "Install app" from the Dev Dashboard → OAuth flow completes successfully (token stored in Prisma
Session table)
- 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
vercel.json rewrite ({ source: "/(.*)", destination: "/" } vs "/$1"): same error. Query params (host, embedded, hmac) confirmed arriving at the function via curl simulation.
- Downgrade
@shopify/app-bridge-react from ^4.2.4 to ^4.1.10: same error.
- Remove
@vercel/react-router preset and react-router.config.ts (when present): same error.
- 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
- Is this a known issue?
- 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)?
- 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.
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
postMessagetarget-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 cloneof this repo, no modifications, no custom Vercel preset, no customvercel.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 mismatchsymptom. The pattern appears to be hosting-pattern-general, not specific to one provider.Steps to reproduce
git clone --depth=1 https://github.com/Shopify/shopify-app-template-react-router.gitcd shopify-app-template-react-router && npm installSHOPIFY_API_KEY,SHOPIFY_API_SECRET,SCOPES,SHOPIFY_APP_URL,DATABASE_URL,DATABASE_URL_UNPOOLED(Postgres / Neon)vercel --prod→ deploy succeeds, app reachable onhttps://<project>.vercel.app/application_urlto the Vercel URL andredirect_urlsto<vercel_url>/auth/callbackshopify app deploy --no-release && shopify app release --version=<v>Sessiontable)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 asshopify app dev(tunnel-based local dev).Actual behavior
The iframe stays blank. Browser console shows:
App Bridge calls
postMessage(msg, targetOrigin)against the parent admin window, buttargetOriginis set to the iframe's own origin (the Vercel app URL) instead ofhttps://admin.shopify.com. The browser blocks the call for cross-origin safety. Downstream, theidTokenrequest to the parent times out because the channel is never established.Environment
Shopify/shopify-app-template-react-routerHEAD (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 symptomreact-router: ^7.12.0@react-router/dev: ^7.12.0fra1(Frankfurt) andiad1(Washington DC) — same symptomThings tried that did NOT fix the issue
vercel.jsonrewrite ({ source: "/(.*)", destination: "/" }vs"/$1"): same error. Query params (host,embedded,hmac) confirmed arriving at the function via curl simulation.@shopify/app-bridge-reactfrom^4.2.4to^4.1.10: same error.@vercel/react-routerpreset andreact-router.config.ts(when present): same error.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
postMessageorigin mismatch symptom). Suggests the bug is hosting-pattern-general.Ask
targetOriginexplicitly, or a meta tag the template should include but doesn't)?Thanks for any pointer.