Reputation: 723
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
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
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