[Fixed]-Django and service workers – serve "sw.js" at application's root url

24👍

You can serve javascript as a view, not just html. Put this in your projects urls.py

url(r'^service-worker.js', cache_control(max_age=2592000)(TemplateView.as_view(
    template_name="service-worker.js",
    content_type='application/javascript',
)), name='service-worker.js'),

Then put your service-worker.js in your templates directory.

Bonus is that you can now also use template tags like static in your javascript file.

👤dalore

5👍

Django 2.2

project structure

myproj/
|-app/
| |-templates/
|   |-app/
|     -sw.js
|-myproj/
  -urls.py

urls.py (project)

from django.views.generic import TemplateView

urlpatterns = [
  ...
  path('sw.js', (TemplateView.as_view(template_name="app/sw.js", 
  content_type='application/javascript', )), name='sw.js'),
]

4👍

In Django 1.11 urls.py should look:

from django.views.generic import TemplateView

urlpatterns = [
  url(r'^sw.js', (TemplateView.as_view(template_name="sw.js", content_type='application/javascript', )), name='sw.js'),
]

3👍

I was getting all the time the error DOMException: The script resource is behind a redirect, which is disallowed.

I spent hours trying to figure out the solution.

Apart from adding at urls.py:

from django.views.generic import TemplateView

urlpatterns = [
  ...,
  url(r'^service-worker.js', (TemplateView.as_view(template_name="service-worker.js", content_type='application/javascript', )), name='service-worker.js'),
]

There was also another step needed.
Instead of

<script>
 if ('serviceWorker' in navigator) {
    console.log("Will the service worker register?");
    navigator.serviceWorker.register('service-worker.js')
      .then(function(reg){
        console.log("Yes, it did.");
     }).catch(function(err) {
       console.log("No it didn't. This happened:", err)
        console.log("err.message:", err.message)
    });
 }
</script>

I used:

<script>
 if ('serviceWorker' in navigator) {
    console.log("Will the service worker register?");
    navigator.serviceWorker.register("{% url 'service-worker.js' %}") //note that I am using the url template here
      .then(function(reg){
        console.log("Yes, it did.");
     }).catch(function(err) {
       console.log("No it didn't. This happened:", err)
        console.log("err.message:", err.message)
    });
 }
</script>
👤J0ANMM

Leave a comment