CORS Preflight Redirect Error with Checkout UI Extension and App Proxy

Hello everyone,

I’m developing a Checkout UI Extension that needs to fetch a json configurations from my backend server through a Shopify app
proxy. However, I’m encountering a persistent CORS error that I cannot resolve. I’ve read that this can be caused by a password protection issue, but I’m unsure how that would be fair to people who do not have access to a Live Shopify Plus subscription and or Paid Partner Plus sandbox site. Im using a Partner Development site with correct config.
(ive changed variables to obfuscate so might be wrong here)

The Error:

Access to fetch at

'https://store-worki1.myshopify.com/apps/app-dev-proxy/endpoint?foo=quick&operation=GET_SOMETHING' from     
origin 'https://extensions.shopifycdn.com' has been blocked by CORS policy: Response to preflight request doesn't pass access       
control check: Redirect is not allowed for a preflight request.

My Setup:

Checkout Extension Code (Checkout.tsx):

const { shop } = useApi();
const sessionToken = useSessionToken();
const checkoutToken = useCheckoutToken();
const shopDomain = shop.myshopifyDomain!;

const PROXY_BASE_URL = useMemo(() =>
  `${shop.storefrontUrl}/apps/app-dev-proxy`,
  []
);

... 
  const currentSessionToken = await sessionToken.get();
  const currentCheckoutToken = checkoutToken;
  // Making the request
  const [quickResponse, enhancedResponse] = await Promise.all([
    fetch(`${PROXY_BASE_URL}/endpoint?foo=quick&operation=GET_SOMETHING`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${currentSessionToken}`,
      }
    }),
    fetch(`${PROXY_BASE_URL}/endpoint?foo=enhanced&operation=GET_SOMETHING`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${currentSessionToken}`,
      }
    })
  ]);

App Proxy Configuration:

shopify.app.dev-1.toml:

[app_proxy]
url = "https://ngrok-ngrok-wombat.ngrok-free.app/api/proxy"
subpath = "app-dev-proxy"
prefix = "apps"

shopify.extension.toml:

[extensions.capabilities]
api_access = true
network_access = true

Backend Route (api.proxy.endpoint.tsx):

export const loader = async ({ request }: LoaderFunctionArgs) => {
    logRequestContext(request, { handler: 'loader' });
    const { admin } = await authenticate.public.appProxy(request);
    const { sessionToken, cors } = await authenticate.public.checkout(request);


    // Handle CORS preflight OPTIONS request
    if (request.method === 'OPTIONS') {
        return cors(new Response(null, { status: 200 }));
    }

    ....

    return cors(Response.json(
        {
            success: true,
            data: foo,
            operation: 'GET_FOO',
            source: configSource,
            fooType: finalfooType,
            shopDomain: shopDomain
        },
        { status: 200 }
    ));

What I’ve Tried:

  • Proper CORS headers in OPTIONS preflight handling
  • Using absolute URLs instead of relative paths
  • Both authenticate.public.appProxy() and authenticate.public.checkout() authentication
  • Verified app proxy configuration in Shopify admin
  • Added cors() wrapper to all responses

The Issue:

The error specifically mentions “Redirect is not allowed for a preflight request”, which suggests that somewhere in the request
chain, there’s a redirect happening during the OPTIONS preflight request that browsers don’t allow. I have logging in my remix file but it cant even reach it.

Questions:

  1. I seen a thread about possibility that the error may appear if your shop is password protected on the frontend, if this is the case how would I be able to bypass this when using a Partner Development store with Shopify Plus? I need the shopify plus features for the purpose of my extension.
  2. Is there a known issue with app proxies and Checkout UI Extensions causing redirects during CORS preflight?
  3. Should I be using a different URL structure for checkout extensions vs regular storefront requests?
  4. Is there a specific way to configure Remix routes to handle app proxy requests from checkout extensions without redirects?

Working Alternative:

When I bypass the app proxy and use a direct external URL (which I don’t want to expose), the requests work perfectly. This
confirms the issue is specifically with the app proxy handling of checkout extension requests.

Any guidance would be greatly appreciated! This seems to be a common issue but I haven’t found a definitive solution.

Environment:

  • Shopify CLI: Latest
  • App: Checkout and account UI extensions are enabled
  • Store: Checkout and Customer Accounts Extensibility feature enabled. But password protected since not a sandbox.
  • Remix: Latest
  • Checkout UI Extensions: 2025-07

If anyone checks this for the same issue, the issue was “UI extension requests made to the App Proxy of password protected shops is not supported. Extension requests come from a web worker which does not share the same session as the parent window.