How to make Flask Heroku app a Progressive Web Application (pwa)

Viewed 1930

I've deployed a simple web application named "ogagnage" with Flask and Heroku (gunicorn). It works perfectly in production and I try now to run it as a Progressive Web Application. Following Heroku instructions, I've created manifest.json and service workerfile (sw.js). Manifest file is recognized by my browsers but not service worker and i unfortunately don't understand why... Manifest.json OK

sw not recognized sw error message

Here is the structure of my project: Directory tree

And here are the code added:

In views.py :

@app.route('/sw.js')
def sw():
    return app.send_static_file('sw.js')

@app.route('/manifest.json')
def manifest():
    return app.send_static_file('manifest.json')

@app.route('/app/static/app.js')
def app_js():
    return app.send_static_file('app.js')

In sw.js :

console.log('Hello from sw.js');

importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.2.0/workbox-sw.js');

if (workbox) {
  console.log("Yay! Workbox is loaded ");

  workbox.precaching.precacheAndRoute([
    {
      "url": "/",
      "revision": "1"
    }
  ]);

  workbox.routing.registerRoute(
    /\.(?:js|css)$/,
    workbox.strategies.staleWhileRevalidate({
      cacheName: 'static-resources',
    }),
  );

  workbox.routing.registerRoute(
    /\.(?:png|gif|jpg|jpeg|svg)$/,
    workbox.strategies.cacheFirst({
      cacheName: 'images',
      plugins: [
        new workbox.expiration.Plugin({
          maxEntries: 60,
          maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
        }),
      ],
    }),
  );

  workbox.routing.registerRoute(
    new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
    workbox.strategies.cacheFirst({
      cacheName: 'googleapis',
      plugins: [
        new workbox.expiration.Plugin({
          maxEntries: 30,
        }),
      ],
    }),
  );
} else {
  console.log("Boo! Workbox didn't load ");
}

In app.js:

    (function() {
      if('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
          navigator.serviceWorker.register('sw.js')
                   .then(function(registration) {
                   console.log('Service Worker Registered');
                   return registration;
          })
          .catch(function(err) {
            console.error('Unable to register service worker.', err);
          });
          navigator.serviceWorker.ready.then(function(registration) {
            console.log('Service Worker Ready');
          });
        });
      }
    })();

In my base template:

 <script type="text/javascript" src="../static/js/app.js"></script>

   

And my git: Github project

Hope someone could help me, it would be a beautiful Christmas present. Tx

2 Answers

You also need to send the manifest.json file

@app.route('/manifest.json')
def manifest():
    return app.send_from_directory('static', 'manifest.json')

If you'd like a complete example, I have created a Flask PWA before. Here is the repository: https://github.com/MurphyAdam/Flask-chatbot

I've solved the problem after changing @app routes in views.py and relative path to go to sw.js in app.js (cf code updated) Now , my service worker is working: Service Worker Ok

Related