DEV Community

Cover image for How to handle PWA and API in the same domain (origin)?
Mateusz Gostański
Mateusz Gostański

Posted on

How to handle PWA and API in the same domain (origin)?

In our brand new project at Evionica I've come across an interesting challenge - how to exclude certain paths from the ServiceWorker.

In deployment architecture we assume that all API microservices along with the authentication service are in the same path as the project. For eg. project.evionica.com is an entry point for our frontend application, so OAuth2 endpoints are in project.evionica.com/rest/auth/.

This causes certain problems with PWA. Why?
Because when frontend is rendered, the service worker will be downloaded & installed very quickly. Let's assume that you enter index.vue (which is the very first view in the app) and are directly redirected to OAuth2 Login page. In such case the service worker will be already running (or at least downloaded in the best case scenario). That means that
every other navigation item in window.location.origin will be handled by the ServiceWorker. This causes a lot of problems when you are using OAuth2 flow in such "URL pattern" architecture.

How to solve this?

OAuth2 URLs should be excluded from URLs being handled by the ServiceWorker. Our ServiceWorker, like most of them, uses Workbox under the hood to easily register assets, manage preloading etc. Workbox allows customizing such behaviour by allowing to define denylist - an array with RegExp-defined paths which should be handled in the classic, standard way by the browser. The denylist is defined by calling registerRoute function. Since we are using generateSW option, we do not manually create & maintain the Service Worker file. The VitePWA plugin & workbox does it for us.

We can still specify how VitePWA creates our service worker file. In our vite.config.ts file, in plugins section, in VitePWA() config object we need to declare workbox key and pass such values:

export default defineConfig(({command, mode}) => {
    return {
        plugins: [
            VitePWA({
                workbox: {
                    navigateFallbackDenylist: [/.*\/rest\/auth(\/.*)?/],
                },
            }),
        ],
    }
})
Enter fullscreen mode Exit fullscreen mode

In the array under the navigateFallbackDenylist key, you can define as many RegExp objects as you need to exclude them
from the Service Worker's "jurisdiction".

Top comments (0)