This works fine in my local development environment, but after deploying to production, I get the following CORS error:
Access to fetch at ‘https://my-app.com/api/point?customerID=…’
from origin ‘https://extensions.shopifycdn.com’ has been blocked by CORS policy:
Response to preflight request doesn’t pass access control check:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
I wrapped the response with cors() from authenticate.admin as documented, but still getting CORS errors on the preflight (OPTIONS) request in
production.
Questions
Does the cors() method handle OPTIONS preflight requests automatically?
Is there additional configuration needed for Admin Block Extensions in production?
I’m currently investigating if there is an issue with the cors() method.
In the meantime, can you confirm if bypassing that method and handling CORS manually works for you?
This is happening because the OPTIONS preflight request never hits your loader in production.
In an Admin UI extension, fetch() sends auth headers, so the browser does an OPTIONS preflight from https://extensions.shopifycdn.com. authenticate.admin().cors() only adds headers to a response you return — it doesn’t magically handle OPTIONS unless your route actually responds to it.
In Remix / React Router v7:
loader handles GET
OPTIONS is ignored unless you handle it explicitly
That’s why it works locally but fails in prod. Check out this thread as well:
Fix
Add an action to handle OPTIONS and wrap it with cors():
Hi, thank you for your response and investigation!
I’m sorry for the confusion — it turned out I was deploying to the wrong environment. After deploying to the correct
environment, the original code from the documentation worked perfectly: