Offline Post Requests With Workbox (VueJS)

If you ever tried creating a PWA you may already know the pain of handling post requests in an offline environment. There are a lot of problems that need to be considered. For example, how do you prevent the request to the server? How do you queue your post requests the right way and why you shouldn’t handle Server IDs (ids of your object on the server)on the client.

Let’s take one problem at a time.

Prevent requests to the server

So how do you prevent requesting your server without changing your production code? It’s actually pretty easy — use workbox ;). I’ve already created a couple of blog posts (Vue PWA Plugin, Vue PWA And IndexedDB) on how to set up a service worker with the Vue PWA Plugin. So please check these first out.

The only command that you need for now is:

vue add @vue/pwa

This will add all the necessary files to your project and you are good to go.

How do you queue your post requests

Queueing your requests is also really important. You certainly don’t want to lose any data that the user submitted while he was offline. Depending on your application it might be sufficient to just use a synchronize button that the user can click when he is online again. But I’ve made the experience that people forget this really fast and if there isn’t fast feedback for them you will only confuse your users. To prevent this you might want to have a tool that synchronizes automatically after the user is online again. Normally this would be a huge task on it’s on but again workbox comes to our help with a plugin called background sync.

Again workbox is really easy to use in this case. To add this capability only add these lines to your service-worker.js

const bgSyncPlugin = new workbox.backgroundSync.Plugin('queueExample', {
maxRetentionTime: 24 * 60 // Retry for max of 24 Hours
});
workbox.routing.registerRoute(
'https://jsonplaceholder.typicode.com/posts',
workbox.strategies.networkOnly({
plugins: [bgSyncPlugin]
}),
'POST'
);

The first line defines the plugin and how long it should run. In my case, I want to enable syncing for at least 24 hours. Depending on your use case you might want to increase this time. The next block defines what happens when the url ‘https://jsonplaceholder.typicode.com/posts' is called. I’m using the networkOnly strategy that will use the bgSyncPlugin defined above. So any time I don’t have any connection to the internet this plugin will be used.

To test the implementation please visit: workbox-sync (Hint: DO NOT USE CHROME DEVTOOLS OFFLINE) Although the cached request will appear within your indexedDB the rest will not work correctly.

So what does the cached request look like?

And that's it. The requests will be cached by your indexedDB and synchronized as soon as you have a stable internet connection (might take some minutes)

Don’t handle your IDs on the client

I know I know… this might be a real downer for you but I wouldn’t recommend generating IDs on your client. First of all the client should never decide how the IDs on the server will be entered. Furthermore, even if you use temp ids on your client you will run really fast into a complexity hell if you reference IDs within your indexedDB. Imagine updating those temp IDs with IDs coming from the server… good luck with that :).

So the best use case for background syncs are fire and forget posts.