- この記事はMDCアドベントカレンダー1日目の記事です
はじめに
- PWAと言われたときにホームスクリーンへ追加できるWebアプリのことと思う方も多いと思います(PWAの定義についてはここではふれません)
- 最近だとライブラリやフレームワークに乗っかることで簡単にホームスクリーンへの追加を実現できるケースが多いですが今回は自前で実装する方法を整理します
機能の概要
- Webアプリをスマホアプリのように端末にインストールしホーム画面にアイコンを設置できます
- ホーム画面のアイコンからアプリを開くとスプラッシュ画面が表示され画面上部にURLバーがない状態で全画面で表示することができます
手順
- ホームスクリーンへ追加の仕組みを入れるためには以下の3つの要件があります
- ServiceWorkerが有効化されていること
- manifestファイルが読み込まれていてそこに設定が記載されていること
- HTTPSで配信されていること
ServiceWorkerが有効化されていること
- ホームスクリーンへ追加の機能を使うためにはServiceWorkerが有効化されている必要があります
- オフラインキャッシュなど他の機能を使わないのであれば細かい実装は不要で読み込むだけでOKです
sw.js
self.addEventListener('fetch', function (event) {});
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Hello PWA</title>
</head>
<body>
<h1>Hello PWA</h1>
<script>
window.addEventListener('load', () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('sw.js')
.then(registration => console.log('registered', registration))
.catch(error => console.log('error', error));
}
});
</script>
</body>
</html>
manifestファイルが読み込まれていてそこに設定が記載されていること
- manifest.webmanifestというファイルを作成してそこにホームスクリーンへ追加の設定をしていきます
manifest.webmanifest
{
"name": "Hello PWA",
"short_name": "Hello",
"start_url": ".",
"display": "standalone",
"background_color": "#4E526F",
"theme_color": "#4E526F",
"icons": [
{
"src": "images/icons-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/icons-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
- nameとshort_nameはアプリ名を記載します
- ホーム画面のアイコンの下に表示される名前などスペースが狭い場面ではshort_nameが使われます
- start_urlはホーム画面から起動したときにどのページを開くかを指定します
- displayは表示モードの指定でfullscreen、standalone、minimal-uiの3つから選びます
- background_colorはスプラッシュ画面の背景色をtheme_colorはツールバーの色を指定します
- iconsにはアプリのアイコンを設定します
- 作成したmanifestファイルをhtml側で読み込めばOKです
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Hello PWA</title>
<!-- ↓manifestファイルの読み込みを追加↓ -->
<link rel="manifest" href="manifest.webmanifest" />
</head>
<body>
<h1>Hello PWA</h1>
<script>
window.addEventListener('load', () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('sw.js')
.then(registration => console.log('registered', registration))
.catch(error => console.log('error', error));
}
});
</script>
</body>
</html>
iPhone対応
- AndroidだけであればこれでいいのですがiPhone向けには専用の設定が必要です
- ホーム画面に追加されるアイコンとスプラッシュ画面の画像を設定します
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- ↓iPhone用にURLバーを表示しない設定を追加↓ -->
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Hello PWA</title>
<link rel="manifest" href="manifest.webmanifest" />
<!-- ↓iPhone用にアイコン設定を追加↓ -->
<link rel="apple-touch-icon" href="images/icons-192.png" />
<!-- ↓iPhone用にスプラッシュ画面の設定を追加↓ -->
<link
rel="apple-touch-startup-image"
href="images/launch-640x1136.png"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="images/launch-750x1334.png"
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="images/launch-1080x1920.png"
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="images/launch-1125x2436.png"
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="images/launch-828x1792.png"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="images/launch-1242x2688.png"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="images/launch-1170x2532.png"
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="images/launch-1284x2778.png"
media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
</head>
<body>
<h1>Hello PWA</h1>
<script>
window.addEventListener('load', () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('sw.js')
.then(registration => console.log('registered', registration))
.catch(error => console.log('error', error));
}
});
</script>
</body>
</html>
- これでコーディングは完了です!
HTTPSで配信されていること
動作確認
- 今回紹介したコードはこちらのサンプルリポジトリに公開してあります
- このコードをGitHub Pagesで公開しています
Android/Chrome
iPhone/Safari
Mac/Chrome
まとめ
- ホームスクリーンへ追加の機能がほしいだけであれば自前でも簡単に実装できることがわかりました
- AndroidとiPhoneで仕様が共通化されてないのがちょっと面倒ですね
- iPhoneのスプラッシュ画面はデバイスサイズこどに用意しないといけないのでそこが一番大変でした
参考サイト
- https://web.dev/app-shortcuts/
- https://web.dev/install-criteria/
- https://web.dev/add-manifest/
- https://developer.mozilla.org/ja/docs/Web/Progressive_web_apps/Add_to_home_screen
- https://docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium
- https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html
- https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/adaptivity-and-layout/