Admin UI Extension → Node.js app backend: fetch() never reaches server (CORS / OPTIONS preflight issue)

Hi everyone,

We’re building an Admin UI Extension (block targeting admin.product-details.block.render) that needs to POST analytics events to our app’s own backend. Our app is built on the Node.js app template (not Remix) with Express.

First off, Is there a recommended approach to handle this flow (Admin UI Extn → Shopify Node App Template backend) for apps that were built on the node app template.

From the extension we call:

fetch("api/admin-block/events", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ eventName, eventProperties }),
});

On the backend (Express), we’ve set up:

  • A `app.use("/api/admin-block", ...)` middleware that sets Access-Control-Allow-Origin: https://extensions.shopifycdn.com on every response.

  • A app.options(…) handler to answer preflights.

We’re not seeing any logs in our backend from this request at all… Totally blank.
We’ve tried a bunch of things but nothing seemed to click.

Is there an official Node.js app template example for Admin UI Extension → backend communication, similar to the Remix authenticate.admin(request) + cors() helper?

Any help is appreciated, especially if you’ve gotten this working on the Node.js template!

Thanks in Advance,
Ishaan

Hey, @Ishaan_Shettigar thanks for flagging and getting in touch. This does seem a bit odd.

If you can, could you share the exact request URL you’re seeing in DevTools for the failing call, along with the full request and response details for one failing attempt, including headers and body, with any secrets or tokens redacted? If there’s an x request id on the response in DevTools as well within the browser itself, plus the date, time, and timezone of the attempt, that would be really helpful too.

If you can share that, I can do some digging on our side and see what might be going on for sure.