PWAの作り方|manifest.json・Service Worker・ホーム画面対応を実例つきで解説
Webサイトをスマホのホーム画面に追加したとき、アプリのように見せたい。
URLバーを消したい。アイコンをちゃんと表示したい。できればオフラインでも少し動いてほしい。
そういう時に使う仕組みがPWAです。
PWAと聞くと難しそうに見えますが、最初に必要なものはそこまで多くありません。
- manifest.json:アプリ名・アイコン・表示方法などを決めるファイル
- Service Worker:キャッシュやオフライン対応を扱う裏側の仕組み
僕もPWA LABを作りながら、manifest、Service Worker、start_url、theme_colorなどを実機でいろいろ試しています。
やってみて思うのは、PWAは「書き方」だけならシンプルです。ただ、実際のスマホで試すと、Android ChromeとiPhone Safariで挙動が違ったり、キャッシュが残って反映されなかったり、かなり泥臭い部分もあります。
この記事では、PWAの基本的な作り方と、実際に作るときに気をつけたいポイントをまとめます。
PWAに最低限必要なもの
PWAを作るために、まず用意するものは次の3つです。
- manifest.json
- Service Worker用のsw.js
- ホーム画面用のアイコン画像
さらに公開環境では、HTTPSも必要です。
難しく見えるかもしれませんが、最初は「manifestで見た目を決める」「Service Workerで裏側の動きを足す」と考えれば十分です。
1. manifest.jsonを作る
manifest.jsonは、PWAの見た目や起動方法を指定するファイルです。
アプリ名、短い名前、起動URL、表示モード、テーマカラー、アイコンなどをここに書きます。
{
"name": "サイト名",
"short_name": "短い名前",
"start_url": ".",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#ffffff",
"icons": [
{
"src": "/icons/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
この中で特に重要なのは、name、start_url、display、iconsです。
- name:アプリ名
- short_name:ホーム画面などで使われる短い名前
- start_url:ホーム画面から開いた時のURL
- display:アプリの表示方法
- icons:ホーム画面アイコン
僕がPWA LABで試していて、特に大事だと感じたのはstart_urlです。
よくある例では "start_url": "/" と書かれますが、ページごとにホーム画面追加したいなら、"start_url": "." の方が自然なケースがあります。
たとえば、ユーザーが特定のページを見て「このページをホームに置きたい」と思ったのに、起動したらトップページに戻されると、少しズレます。
特別な理由がないなら、最初は "start_url": "." で考えてみるのもありです。
👉 PWAとは?スマホのWebサイトを“アプリ化”する仕組みをわかりやすく解説 の解説が役に立ちます。
2. HTMLからmanifest.jsonを読み込む
manifest.jsonを作ったら、HTMLのhead内に読み込みタグを追加します。
<link rel="manifest" href="/manifest.json">
これでブラウザがmanifestを読みに行けるようになります。
ただし、PWAを作っていると、ここで地味にハマることがあります。
たとえば、パスを1文字間違えているだけでmanifestは読み込まれません。僕もPWA LABで /lab/manifest.json のつもりが、別のパスになっていて、しばらく悩みました。
ChromeのDevToolsでManifestを確認すると、読み込めているかどうかをチェックできます。
また、サーバー側で返すContent-Typeは、できれば次のようにしておくと安心です。
application/manifest+json
Cloudflare Workersなどで自分で返す場合は、MIMEタイプの指定も忘れない方がいいです。
3. Service Workerを用意する
Service Workerは、PWAの裏側で動くJavaScriptです。
キャッシュ、オフライン対応、Push通知など、アプリっぽい挙動に関わる部分を担当します。
最小構成なら、まずはこれくらいでも登録できます。
self.addEventListener("install", (event) => {
console.log("Service Worker installed");
});
self.addEventListener("activate", (event) => {
console.log("Service Worker activated");
});
この段階では、まだキャッシュ制御はしていません。
Service Workerを登録しているだけです。
次に、HTMLまたはJSからService Workerを登録します。
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/sw.js");
}
これで、対応ブラウザではService Workerが登録されます。
ただし、Service Workerは一度登録されるとキャッシュが強く残ることがあります。
ここがPWAでよくある「変更したのに反映されない」問題につながります。
4. キャッシュ対応を入れる
PWAらしさを出すなら、Service Workerで必要なファイルをキャッシュします。
たとえば、トップページ、manifest、アイコンをキャッシュする場合は、次のように書けます。
const CACHE_NAME = "my-pwa-v1";
const FILES_TO_CACHE = [
"/",
"/manifest.json",
"/icons/icon-512.png"
];
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(FILES_TO_CACHE);
})
);
});
self.addEventListener("fetch", (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
これはかなりシンプルなCache Firstの例です。
キャッシュにあればキャッシュを返し、なければネットワークから取得します。
オフライン対応には強いですが、更新反映が遅くなることがあります。
実際、PWA LABでもCache Firstを試すと、オフラインでは強くなりますが、古いファイルが残り続ける感じも出ます。
更新頻度が高いサイトなら、Network FirstやStale While Revalidateのような考え方も必要になります。
キャッシュ戦略については、PWAのキャッシュ戦略を完全に理解するでも詳しく整理しています。
5. アイコン画像を用意する
PWAでは、ホーム画面に表示されるアイコン画像がかなり重要です。
基本的には、次のサイズを用意しておくと安心です。
- 192×192
- 512×512
特にAndroid Chromeでは、manifestのiconsがかなり重要です。
画像が小さすぎたり、パスが間違っていたりすると、ホーム画面追加時に意図したアイコンが出ないことがあります。
iPhoneの場合は、manifestだけでなく、apple-touch-iconも入れておくと安定しやすいです。
<link rel="apple-touch-icon" href="/icons/icon-512.png">
iPhoneのホーム画面アイコンは、ブラウザやiOSのキャッシュの影響を受けることがあります。
アイコンを変えたのに古いままになる場合は、キャッシュやホーム画面追加済みアイコンの再作成が必要になることもあります。
このあたりは、iPhoneのアイコンが更新されない理由でも詳しく書いています。
6. HTTPSで公開する
PWAは、基本的にHTTPS環境で動かす必要があります。
Service Workerはセキュリティ上、HTTPSでないと登録できません。
ローカル開発の localhost は例外ですが、公開するサイトではHTTPSが必須です。
今はCloudflare Pages、Cloudflare Workers、GitHub Pages、Vercelなどを使えば、HTTPS自体はかなり簡単に用意できます。
昔よりも、PWAを試すハードルはかなり下がっています。
7. ホーム画面に追加して実機で確認する
ここまでできたら、実際にスマホで確認します。
AndroidならChromeでサイトを開き、メニューからインストールまたはホーム画面に追加します。
iPhoneならSafariでサイトを開き、共有ボタンからホーム画面に追加します。
確認するポイントは次の通りです。
- ホーム画面に正しいアイコンが出るか
- アプリ名が意図通りか
- 起動時のURLが意図通りか
- ブラウザUIが消えるか
- theme_colorやbackground_colorが反映されるか
- オフライン時にどう動くか
ここで大事なのは、PCのDevToolsだけで判断しないことです。
PWAは、Android Chrome、iPhone Safari、PC Chromeで挙動が違います。
特にiPhoneは、Androidほどmanifestの指定が素直に反映されないことがあります。
なので、最終的には実機確認が一番大事です。
PWAでよくある失敗
実際にPWAを作ると、地味なミスで止まることが多いです。
- manifest.jsonのパスが間違っている
- manifestのMIMEタイプが正しくない
- iconsの画像パスが間違っている
- Service Workerのスコープが想定と違う
- 古いキャッシュが残って更新されない
- iPhoneとAndroidで見た目が違う
特に多いのは、パスとキャッシュです。
1文字違うだけでmanifestは読まれませんし、Service Workerのキャッシュが残ると、直したはずのファイルがなかなか反映されません。
PWAは未来感がありますが、実装はかなり泥臭いです。
でも、この泥臭さを一回理解すると、Webサイトをホーム画面に置く体験をかなり自由に作れるようになります。
PWAは「manifest」と「Service Worker」のセットで考える
PWAは、単にホーム画面に追加できるだけの仕組みではありません。
manifest.jsonで見た目を指定し、Service Workerで裏側の挙動を作ることで、Webサイトをアプリに近づける仕組みです。
- manifest.json:名前、アイコン、表示モード、色、起動URL
- Service Worker:キャッシュ、オフライン対応、更新制御
- アイコン:ホーム画面での見え方
- HTTPS:Service Workerを動かすために必要
まずは最小構成で作って、ホーム画面に追加して、実機で動きを見る。
そこからキャッシュ、オフライン対応、start_url、theme_colorなどを少しずつ調整していくのが一番わかりやすいです。
まとめ:PWAは作るだけなら簡単。でも実機検証が大事
PWAを作る基本手順はシンプルです。
- manifest.jsめ:PWAは作るだけなら簡単。でも実機検証が大事
PWAを作る基本手順はシンプルです。
- manifest.jsonを作る
- HTMLからmanifestを読み込む
- Service Workerを作る
- Service Workerを登録する
- アイコン画像を用意する
- HTTPSで公開する
- スマホのホーム画面に追加して確認する
ここまでできれば、Webサイトをアプリのように見せる基本は整います。
ただし、PWAはブラウザやOSによって挙動が変わります。
Androidでは反映されるのにiPhoneでは変わらない。キャッシュが残って古い表示になる。manifestを直したのに反映が遅い。
こういうことは普通に起きます。
だからこそ、PWAはコードを書くだけでなく、実際にスマホで試すところまでがセットです。
Webサイトをアプリ化したい人、ホーム画面追加に対応したい人、軽いWebツールを作りたい人にとって、PWAはかなり強力な選択肢になります。