PSA: elm/http works with ServiceWorker

Hi folks!

Every so often I’ll see questions pop up about using Elm in a progressive web app, to which people reply that you can’t use elm/http and intercept those requests with a ServiceWorker because elm/http uses XMLHttpRequest and not fetch. This seems to come up on Reddit most often, but I asked around and learned that this misunderstanding is quite common! So here’s a clarification:

ServiceWorker will intercept any HTTP request from a client except WebSocket upgrade requests.

This means requests made with fetch, requests made with XMLHttpRequest, requests the browser makes for the src of an img, and even requests that happen through the browser’s navigation bar.

We use use a ServiceWorker at NoRedInk to manage certain infrastructure-level response codes before responding to requests made with elm/http. I recently wrote a proof-of-concept program that hosts an entire GraphQL endpoint in a ServiceWorker and uses dillonkearns/elm-graphql to make requests to it. Here is an example of a PWA Hacker News clone built with Elm. You can open it up and watch the network tab of your devtools to get an idea of how it works.

I think the misunderstanding might be coming from the fact that you can only use fetch to make requests from within a ServiceWorker. You wouldn’t be able to write a ServiceWorker implementation using elm/http. This is to be expected, as ServiceWorker implementations are not a part of Elm’s design.

Anyway, my hope is that this post can be useful for linking whenever this topic comes up on Reddit or in Slack or elsewhere on here. For questions and discussion let’s open up new topics.

Thank you to @jessta, @dmy, and rlking in Slack for talking through this issue with me.