PWAの作り方|manifest.json・Service Worker・ホーム画面対応を丁寧に解説

WebサイトをPWA化するための手順を、manifest.json や Service Worker を中心にわかりやすく解説。初心者〜中級者向けの実装ガイド。スマホで“アプリのように動く”Webサイトを作る手順まとめ。

目次

Webサイトをスマホのホーム画面に追加したとき、アプリのように見せたい。

URLバーを消したい。アイコンをちゃんと表示したい。できればオフラインでも少し動いてほしい。

そういう時に使う仕組みがPWAです。

PWAと聞くと難しそうに見えますが、最初に必要なものはそこまで多くありません。

僕もPWA LABを作りながら、manifest、Service Worker、start_url、theme_colorなどを実機でいろいろ試しています。

やってみて思うのは、PWAは「書き方」だけならシンプルです。ただ、実際のスマホで試すと、Android ChromeとiPhone Safariで挙動が違ったり、キャッシュが残って反映されなかったり、かなり泥臭い部分もあります。

この記事では、PWAの基本的な作り方と、実際に作るときに気をつけたいポイントをまとめます。

PWAに最低限必要なもの

PWAを作るために、まず用意するものは次の3つです。

さらに公開環境では、HTTPSも必要です。

難しく見えるかもしれませんが、最初は「manifestで見た目を決める」「Service Workerで裏側の動きを足す」と考えれば十分です。

1. manifest.jsonを作る

manifest.jsonは、PWAの見た目や起動方法を指定するファイルです。

アプリ名、短い名前、起動URL、表示モード、テーマカラー、アイコンなどをここに書きます。

JSON
{
 "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です。

僕がPWA LABで試していて、特に大事だと感じたのはstart_urlです。

よくある例では "start_url": "/" と書かれますが、ページごとにホーム画面追加したいなら、"start_url": "." の方が自然なケースがあります。

たとえば、ユーザーが特定のページを見て「このページをホームに置きたい」と思ったのに、起動したらトップページに戻されると、少しズレます。

特別な理由がないなら、最初は "start_url": "." で考えてみるのもありです。

2. HTMLからmanifest.jsonを読み込む

manifest.jsonを作ったら、HTMLのhead内に読み込みタグを追加します。

HTML
<link rel="manifest" href="/manifest.json">

これでブラウザがmanifestを読みに行けるようになります。

ただし、PWAを作っていると、ここで地味にハマることがあります。

たとえば、パスを1文字間違えているだけでmanifestは読み込まれません。僕もPWA LABで /lab/manifest.json のつもりが、別のパスになっていて、しばらく悩みました。

ChromeのDevToolsでManifestを確認すると、読み込めているかどうかをチェックできます。

また、サーバー側で返すContent-Typeは、できれば次のようにしておくと安心です。

Text
application/manifest+json

Cloudflare Workersなどで自分で返す場合は、MIMEタイプの指定も忘れない方がいいです。

3. Service Workerを用意する

Service Workerは、PWAの裏側で動くJavaScriptです。

キャッシュ、オフライン対応、Push通知など、アプリっぽい挙動に関わる部分を担当します。

最小構成なら、まずはこれくらいでも登録できます。

JavaScript
self.addEventListener("install", (event) => {
 console.log("Service Worker installed");
});

self.addEventListener("activate", (event) => {
 console.log("Service Worker activated");
});

この段階では、まだキャッシュ制御はしていません。

Service Workerを登録しているだけです。

次に、HTMLまたはJSからService Workerを登録します。

Text
if ("serviceWorker" in navigator) {
 navigator.serviceWorker.register("/sw.js");
}

これで、対応ブラウザではService Workerが登録されます。

ただし、Service Workerは一度登録されるとキャッシュが強く残ることがあります。

ここがPWAでよくある「変更したのに反映されない」問題につながります。

4. キャッシュ対応を入れる

PWAらしさを出すなら、Service Workerで必要なファイルをキャッシュします。

たとえば、トップページ、manifest、アイコンをキャッシュする場合は、次のように書けます。

JavaScript
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では、ホーム画面に表示されるアイコン画像がかなり重要です。

基本的には、次のサイズを用意しておくと安心です。

特にAndroid Chromeでは、manifestのiconsがかなり重要です。

画像が小さすぎたり、パスが間違っていたりすると、ホーム画面追加時に意図したアイコンが出ないことがあります。

iPhoneの場合は、manifestだけでなく、apple-touch-iconも入れておくと安定しやすいです。

HTML
<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でサイトを開き、共有ボタンからホーム画面に追加します。

確認するポイントは次の通りです。

ここで大事なのは、PCのDevToolsだけで判断しないことです。

PWAは、Android Chrome、iPhone Safari、PC Chromeで挙動が違います。

特にiPhoneは、Androidほどmanifestの指定が素直に反映されないことがあります。

なので、最終的には実機確認が一番大事です。

PWAでよくある失敗

実際にPWAを作ると、地味なミスで止まることが多いです。

特に多いのは、パスとキャッシュです。

1文字違うだけでmanifestは読まれませんし、Service Workerのキャッシュが残ると、直したはずのファイルがなかなか反映されません。

PWAは未来感がありますが、実装はかなり泥臭いです。

でも、この泥臭さを一回理解すると、Webサイトをホーム画面に置く体験をかなり自由に作れるようになります。

PWAは「manifest」と「Service Worker」のセットで考える

PWAは、単にホーム画面に追加できるだけの仕組みではありません。

manifest.jsonで見た目を指定し、Service Workerで裏側の挙動を作ることで、Webサイトをアプリに近づける仕組みです。

まずは最小構成で作って、ホーム画面に追加して、実機で動きを見る。

そこからキャッシュ、オフライン対応、start_url、theme_colorなどを少しずつ調整していくのが一番わかりやすいです。

まとめ:PWAは作るだけなら簡単。でも実機検証が大事

PWAを作る基本手順はシンプルです。

ここまでできれば、Webサイトをアプリのように見せる基本は整います。

ただし、PWAはブラウザやOSによって挙動が変わります。

Androidでは反映されるのにiPhoneでは変わらない。キャッシュが残って古い表示になる。manifestを直したのに反映が遅い。

こういうことは普通に起きます。

だからこそ、PWAはコードを書くだけでなく、実際にスマホで試すところまでがセットです。

Webサイトをアプリ化したい人、ホーム画面追加に対応したい人、軽いWebツールを作りたい人にとって、PWAはかなり強力な選択肢になります。

ショートカット・Webアプリ方式・OJapp方式を徹底比較

ショートカット方式・通常のホーム画面追加・OJapp方式の3つを比較。手軽さ、再現性、共有性、デザイン面での違いを解説します

おじゃち

OJapp代表 WPプラグインPWAマーケティング・OnePage.OneApp.(1P1A)・ホーム画面名刺&SNSのPetal・その他OJappToolsなどを開発。PWA・ホーム画面・Safari挙動・軽量Web体験を中心に、実験しながらWebアプリを開発しています。

← 記事一覧へ戻る