Kaiss Bouali
Kaiss Bouali

Reputation: 105

PWA not working properly with Django using Service Workers

I developed a small prototype in django with one model: Profile, and 2 templates with 2 views (a list of profiles, and an edit profile page), with a form in forms.py. I want to test creating a PWA with Django and this is the additional things I did: 1) pip install django-progressive-web-app, 2) added 'pwa' to installed apps, 3) added a render view for the base.html that will be using the service worker!

def base(request):
    return render(request,'app/base.html')

4) added it to the urls:

urlpatterns = [
    path(r'', profiles, name="profiles"),
    path('user/<pk>', profile, name="profile"),
    path('', include('pwa.urls')),
]

5) added this to recognise the service worker:

PWA_SERVICE_WORKER_PATH = os.path.join(BASE_DIR, 'posts/static/js', 'serviceworker.js')

6) added the tags:

{% load pwa %}

<head>
    ...
    {% progressive_web_app_meta %}
    ...
</head>

7) and added this to a serviceworker.js file, situated in the app/static/js:

var staticCacheName = 'djangopwa-v1';

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(staticCacheName).then(function(cache) {
      return cache.addAll([
        '/base_layout'
      ]);
    })
  );
});

self.addEventListener('fetch', function(event) {
  var requestUrl = new URL(event.request.url);
    if (requestUrl.origin === location.origin) {
      if ((requestUrl.pathname === '/')) {
        event.respondWith(caches.match('/base_layout'));
        return;
      }
    }
    event.respondWith(
      caches.match(event.request).then(function(response) {
        return response || fetch(event.request);
      })
    );
});

What happened is that the service worker is running under Chrome developer tool, but in the django console it displays this error: Not Found: /base_layout, and the homepage is accessible through the Offline mode, but the other path (/user) isn't. And Google Chrome's console displays this error:

The FetchEvent for "http://localhost:8000/manifest.json" resulted in a network error response: the promise was rejected.
Promise.then (async)
(anonymous) @ serviceworker.js:19
serviceworker.js:1 Uncaught (in promise) TypeError: Failed to fetch

Also, images are not being loaded.

What did I do wrong?

Upvotes: 3

Views: 2044

Answers (1)

lordsarcastic
lordsarcastic

Reputation: 369

For the images, add the images url to the array passed to the cache.addAll method. Like so:

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(staticCacheName).then(function(cache) {
      return cache.addAll([
        '/base_layout',
        '/static/img-1.png',
        '/static/img-2.png',
      ]);
    })
  );
});

To ensure your css and js files load, also add their paths to the array.

Upvotes: 0

Related Questions