Calling `fetch` never resolves in POS UI extension

Hey there,

We have a POS UI extension that renders the same React component in two targets:
pos.purchase.post.action.render and pos.order-details.action.render.

The component initially shows a loading Screen and then makes an external request to our API via fetch inside a useEffect. On the order-details surface this consistently works, but on the post-purchase surface the screen often stays in the loading state even though the backend returns 200 OK immediately. Closing the modal and reopening it makes the data appear correctly.


Observed behavior

  • The console shows the fetch being dispatched, but no “response received” log appears while the modal is open — the spinner never stops.
  • DevTools shows the network request as “waiting”, even though the response headers and body are already available (CORS headers are correct).
  • Rails logs confirm the request finishes with 200 OK.
  • Reopening the modal — or rendering the same component on the order-details surface — always succeeds.
    (Sometimes, if we wait too long, it also gets stuck in a never-ending loading state.)

We’ve observed this issue for the past six months, across multiple iPadOS versions and Shopify POS app versions.


Summary

It looks like the first fetch on pos.purchase.post.action.render never resolves while the modal is open, despite the backend completing the response.
It does resolve after the modal is closed.


Question

Has anyone encountered this behavior, and is there a known workaround or best practice to ensure the request reliably resolves on the post-purchase surface?

Thanks!

I’d appreciate anyone from @shopify team to give some feedback or guidance on this issues. Thank you!

I think if dev tools are showing the network request is ‘waiting’, it would normally point to a server-side issue, whereby a response is being streamed isn’t terminated/ended, or is being kept alive instead of closed etc.

I would suggest sharing your POS specific code (the useEffect), and also a screenshot of the request/response?

One easy test you could do is do a request to https://jsonplaceholder.typicode.com/ (or similar), and see if that has the same issue?