user3655574
user3655574

Reputation: 723

Django progressive web app caching and fetching of templates issue

I am trying to run my django application with a progressive web application, but it seems to be an issue that for my service worker to run, it needs to run in the same folder as all my templates. Unfortunately, on django applications, templates are organised into different modules/apps.

Based on tutorials - the service worker file(sw.js) needs to be in the same folder as the templates that will be cached see Service worker is caching files but fetch event is never fired . but based on the tutorial on youtube at https://youtu.be/70L8saIq3uo?t=1252 it looks like it can be done by including the {% url “urltobecached” %}. But that brings to the question how to get the sw.js file to read from all the templates that needs to be cached since they need to be all inside the same folder as sw.js which is in the static folder. I wasn't able to locate any resource that can solve this issue. Anyone has any experience on this to suggest how to do this?

Below is a sample of all the relevant code

home.html

{% load staticfiles %}

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Testing</title>
  <link rel="stylesheet" href="{% static 'styles.css' %}">

</head>

<body>

<script type="text/javascript">

  if ('serviceWorker' in navigator){
      try {
        navigator.serviceWorker.register("{% static 'sw.js' %}")
        console.log('sw registered')
      } catch (error) {
        console.log('sw reg failed')
      }
    }

</script>

</body>

</html>

sw.js

const staticAssets = [
    './styles.css',
    // '{% url "test1" %}',
]


self.addEventListener('install', async function(event){
    const cache = await caches.open('news-static'); //getting a handle on the cache
    cache.addAll(staticAssets) //caching all the static assets for later
    console.log('installed')
})


self.addEventListener('fetch', function(event){
    console.log('fetch event also not firing')

})

views.py

from django.shortcuts import render
from django.views.generic import TemplateView, View
# Create your views here.
from django.http import HttpResponse
import os

class HomeView(TemplateView):
    template_name = "home.html"

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

class Test1View(TemplateView):
    template_name = "test1.html"

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

urls.py

from django.contrib import admin
from django.urls import path
from jsref.views import HomeView, Test1View
# from jsref.views import index

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'', HomeView.as_view(), name='Home'),
    path(r'test1/', Test1View.as_view(), name='test1')

]

For anyone who wants to test it. I have it on github at https://github.com/yuong1979/pwa

Upvotes: 0

Views: 799

Answers (2)

H&#229;ken Lid
H&#229;ken Lid

Reputation: 23064

The service worker is entirely client side. It doesn't matter what your server folder structure is, or whether pages are created from templates, static html pages or whatever.

The service worker default scope is the path its served from. So if you want all the routes of your django app to be in scope, you have to set up your url routing to serve the service worker js file from your web site root path.

https://example.com/sw.js

So you must configure either django's url router or your webserver to use that route, if you need your entire site to be in scope.

For example, you can configure an alias in nginx like so.

location /sw.js { alias /static/sw.js; }

And make sure you use the root path in your javascript code as well.

navigator.serviceWorker.register("/sw.js")

Upvotes: 1

Harish Karthick
Harish Karthick

Reputation: 720

Basically, The service worker needs to be in the root directory of your application to cache all pages ref:MDN-link

The service worker will only catch requests from clients under the service worker's scope. The max scope for a service worker is the location of the worker.

Upvotes: 1

Related Questions