DjangoでPWAに対応させてみよう!
趣味でお年寄り・認知症の方向けアプリを作る中で、URLなどの余計なバーを排除したいと思いPWAをやってみました!
記事が少なかったり、わからないことが多く、かなり時間を使ってしまいました💦
躓いたところをわかりやすく説明していこうと思います!(当方大学生で勉強中のため至らないところずくしです💦)
必要なもの・準備・基礎知識
基本情報として必要なものを先に書いておきます!(ほぼすべてコピペで実装可能です!!)
・project startとappが済んでいる前提です!
・manifest.json(アプリアイコンや名前を記載する)
・service-worker.js(オフラインでも動作するようにキャッシュなどを管理する)
・base.html(link relでbase.htmlにmanifest.jsonをインポート?して他HTMLで継承して使う)
・ngrok(HTTPSでしかPWAは動作しないので、今回はngrokを使用してHTTPS通信にする)
まずはdjango-pwaをインストールします
pip install django-pwa
settings.pyのINSTALLED_APPSに使用するアプリとして登録します
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
'storages',
'pwa', #追加
]
Staticフォルダを指定します(お好みのフォルダ)
今回は、ルートディレクトリにbackendとfrontendがあり、BASE_DIRにルートが設定されているので、ルートのフロントエンドのスタティックフォルダがStaticフォルダとして指定されています。
Staticの中にmanifestやservice_worker.jsonを起きていきたいと思います。
"""Staticの設定"""
STATIC_URL = "/static/"
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'frontend', 'static'),
]
manifest.jsonを書く
今回の場合、frontend/static/がありさらに、cssフォルダとjsフォルダを作っています
今回、manifest.jsonは
frontend/static/manifest.json
に作りたいと思います。
以下をコピーして、ご自身の内容に変えていきます。
{
"name": "アプリの名前を書く",
"short_name": "短い名前",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#000000",
"icons": [
{
"src": "小さいアイコンのパス",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "大きいアイコンのパス",
"sizes": "512x512",
"type": "image/png"
}
]
}
start_urlはpwaアプリがどこから始まるかを記載します。(めちゃ重要)
今回の場合、/を指定しているので、ルートURLからスタートになります。
例えば、
https://名前/top
というURLがあったときに、
"start_url": "https://名前/top",
と指定すると、topから始まるurlのみがPWAの対象になります。
つまり、https://名前/top/detail
などのtop/を経由するurlしか対象になりません。
すべてのサイトにPWAを適応するためには、
start_urlをルートURLから記載する必要があります。
すべてのサイトにPWAが適応されない問題があるときは、どこからPWAが開始されているかを調べてみると解決するかもしれません。
service_worker.jsを書く
キャッシュを管理するjsらしいです。(詳しいことは知りませんが、キャッシュについていろいろと指定できるらしいです)
self.addEventListener('fetch', function(event) {});
テンプレートでPWAを使えるようにする
今回はbase.htmlにPWA関連をインポートして、ほかのファイルにも継承して使えるようにしようと思います
<!DOCTYPE html>
<html lang="ja">
{% load static %} <!-- staticを読み込む -->
{% load pwa %} <!-- pwaを読み込む -->
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#000000">
<!-- PWA関連コピペ -->
<link rel="manifest" crossorigin="use-credentials" href="{% static 'manifest.json' %}">
{% progressive_web_app_meta %}
<title>{% block title %}My Django PWA{% endblock %}</title>
<!-- サービスワーカーを登録 -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('{% static "js/service_worker.js" %}').then(function(registration) {
console.log('ServiceWorker registered with scope:', registration.scope);
}).catch(function(error) {
console.log('ServiceWorker registration failed:', error);
});
});
}
</script>
</head>
<body>
{% block content %}
<!-- コンテンツはここに挿入されます -->
{% endblock %}
</body>
</html>
重要なところ
crossoriginを書かないと動かなかったし、{% progressive_web_app_meta %}を指定しないと動かなかった
{% load pwa %}
<!-- PWA関連コピペ -->
<link rel="manifest" crossorigin="use-credentials" href="{% static 'manifest.json' %}">
{% progressive_web_app_meta %}
そして、使いたいページに継承する
base.htmlにload staticを記載していても、継承先のHTMLでもload staticは必須
{% extends "base.html" %}
{% load static %}
これにて完成!!
ngrokでHTTPS通信にして動作確認
↓ngrok使い方参考
https://qiita.com/Wadachan69/items/590b5b9c1c916b59a54c
python manage.py runserverして、
ngrokで
ngrok http 8000
で公開
インストールできるか確認!
躓いたところ
・manifestで正しくアイコンを指定していないと動かない
・start_urlがルートになっていなかった(途中で詳しく解説しています)
・base.htmlでのpwaの読み込み方が分からなかった
まとめ!
情報が少なく、むずかった!!