Make the web app installable as a PWA (Tier 1: app shell + offline fallback)

Adds a manifest, service worker, and branded icons so the site can be
installed to a home screen/desktop, plus an offline fallback page so a
dropped connection shows something friendlier than the browser's default
error. Icons are rasterized from the existing favicon.svg mark via
rsvg-convert. The manifest and service worker are served through small
Django views (not raw static files) so their asset URLs pick up
WhiteNoise's content-hashed filenames in prod/selfhosted, and the service
worker is served from the site root so its scope covers the whole app.

Does not include true offline task data or Web Push notifications --
those are tracked separately as larger follow-up projects.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Keith Smith
2026-09-04 22:03:12 -06:00
co-authored by Claude Sonnet 5
parent a23600a486
commit 30c61351de
11 changed files with 136 additions and 1 deletions
+7 -1
View File
@@ -6,18 +6,24 @@ from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.views.generic import TemplateView
from users.urls import api_urlpatterns as users_api_urls, web_urlpatterns as users_web_urls
from tasks.urls import api_urlpatterns as tasks_api_urls, web_urlpatterns as tasks_web_urls
from sync.urls import api_urlpatterns as sync_api_urls
from notifications.urls import api_urlpatterns as notifications_api_urls
from tasks.views_debug import debug_user_agent
from .views import api_root
from .views import api_root, manifest_webmanifest, service_worker
urlpatterns = [
# Admin
path('admin/', admin.site.urls),
# PWA
path('manifest.webmanifest', manifest_webmanifest, name='manifest'),
path('sw.js', service_worker, name='service-worker'),
path('offline/', TemplateView.as_view(template_name='offline.html'), name='offline'),
# Debug endpoint (remove in production)
path('debug/user-agent/', debug_user_agent, name='debug-user-agent'),