App works locally but shows blank page after deploy on Vercel + Neon

What I’ve done so far:

  • Built a Shopify Remix app using the official template.

  • Local dev (shopify app dev) works perfectly → app loads inside Shopify Admin iframe, Product Page extension also shows.

  • Deployed app to Vercel (frontend) + Neon Postgres (database).

  • Set environment variables in Vercel:

    • SHOPIFY_API_KEY, SHOPIFY_API_SECRET, SHOPIFY_APP_URL=https://chicagoprint-pros.vercel.app

    • SCOPES=read_products,write_products

    • DATABASE_URL (Neon connection string with ?sslmode=require)

    • SESSION_SECRET (32+ char random string)

  • Build succeeds on Vercel, no errors in logs.

  • Shopify Partner Dashboard App URL + Redirect URLs match Vercel domain.

The problem:

  • When I open the app from Shopify Admin → Apps → Chicago App, the iframe is completely blank.

  • Local dev works fine, but production deploy on Vercel does not render anything.

  • Vercel logs show requests hitting /auth/login and /app, but no visible UI.

  • No console errors inside Shopify Admin iframe.

What I’ve checked:

  • root.tsx includes addDocumentResponseHeaders (so CSP headers are set).

  • _index.tsx only redirects to /app.

  • auth.login.tsx and auth.$.tsx are correct.

  • app._index.tsx renders a Polaris <Page> (works locally).

  • Database migrations applied successfully on Neon.

Question: Why does the app render fine locally but show a blank page when deployed on Vercel + Neon?

Hello!
I had a similar issue when deploying my Shopify app on a VPS with Ubuntu it worked perfectly in local development, but once deployed, the app page on Shopify was just blank.
After digging around, here’s what fixed it for me, I added the following lines to my

Dockerfile:
ARG SHOPIFY_APP_URL
ARG SHOPIFY_API_KEY
ARG SHOPIFY_API_SECRET
ENV SHOPIFY_APP_URL=${SHOPIFY_APP_URL}
ENV SHOPIFY_API_KEY=${SHOPIFY_API_KEY}
ENV SHOPIFY_API_SECRET=${SHOPIFY_API_SECRET}

to my Dockerfile

Then in my docker-compose.yml, I made sure to pass those arguments so i include them as environment variables:

build:
context: .
args:
SHOPIFY_APP_URL: ${SHOPIFY_APP_URL}
SHOPIFY_API_KEY: ${SHOPIFY_API_KEY}
SHOPIFY_API_SECRET: ${SHOPIFY_API_SECRET}
container_name: yuva-shopify-app
restart: unless-stopped
env_file: .env
environment:
NODE_ENV: production
PORT: ${PORT:-3000}
SHOPIFY_APP_URL: ${SHOPIFY_APP_URL}
SHOPIFY_API_KEY: ${SHOPIFY_API_KEY}
SHOPIFY_API_SECRET: ${SHOPIFY_API_SECRET}

also watch out for comments in .env files,
this is another issue I ran into, in my .env i had
SHOPIFY_API_KEY=my_current_api_key#my_legacy_api_key

and the builder was reading the commented key too.

I don’t know what else could help, I struggle on this for two full day.
I hope it will save time for someone