Cloudflare Tunnels and Cors ISSUE | BUG

I’m encountering an issue when using Shopify CLI to run my app in development.

I’m building a Shopify app with the Node + Express template, which includes a checkout extension that needs to make network requests. Since checkout extensions run in a web worker, Shopify’s documentation states that I must return Access-Control-Allow-Origin: * in the preflight response headers to allow CORS.

However, when I start my server using shopify app dev (which sets up a Cloudflare tunnel), the Access-Control-Allow-Origin: * header is stripped from the preflight response, causing CORS to fail.

In contrast, when I run my Express server manually and set up an ngrok tunnel myself (without using Shopify CLI), this issue does not occur.

As shown above, the first response comes from Cloudflare, which appears to be the cause of the issue.

Some may suggest using the --tunnel-url flag to pass my manually created ngrok URL to the CLI, as mentioned in the documentation. However, I tried this, and the issue persists. It seems that Shopify CLI, regardless of whether it uses Cloudflare or ngrok, modifies the tunnel setup in a way that prevents the required CORS headers from being returned.

To clarify:
:white_check_mark: Manually setting up an ngrok tunnel works without issue.
:cross_mark: Using Shopify CLI to tunnel (with both Cloudflare and ngrok) causes CORS to fail.

Has anyone encountered this before, or found a workaround?

Can confirm this behavior - I stumbled over that a while ago

I am having the same issue. Did you find a solution?

Unfortunately, I did not find a solution. I ended up testing changes by the manual method I explained above. Everything ends up working end-to-end in production.

I opened a PR for this because I believe the issue is in Shopify CLI itself:

The shopify app dev reverse proxy seems to swallow or mishandle CORS preflight OPTIONS requests. Those requests never reach the local backend, so the app cannot return its own CORS headers. The browser then blocks the actual request.

That explains why:

  • the same backend works with a manually managed tunnel
  • it fails through shopify app dev
  • production can still work fine

I documented the repro here:

The PR fixes this by handling preflight requests directly in the CLI reverse proxy. If others here are seeing the same behavior, confirmation on the GitHub issue/PR would be helpful.

Hey,

I’ve just tried this myself and am able to send OPTION requests without issues to my own, local backend

That said, I’m using the react router backend and I’ve found a report similar to yours for the express version of apps. Have you tried the proposed workaround here yet: [Bug]: shopify app dev with cloudflare quick tunnel not proxying OPTIONS requests · Issue #5660 · Shopify/cli · GitHub ?

Thanks!