yarn create vite m
y-app --template react-ts
で作ったプロジェクトをPWA化するための簡単なメモです。ここでのPWA化とはインストール可能とすることを目的としています。
方法
Vite Plugin PWAを使いました。
iOSはSafari限定で「ホーム画面に追加」からおこないます。
詳細
パッケージのインストール
yarn add vite-plugin-pwa -D
public/robots.txtの追加
robots.txt
は、検索エンジンのクロール(サイトを巡回し、ページの内容を収集・保存する処理)を制御するためのファイルだそうです。例えば私のGatsbyのブログのそれは https://blog.pitang1965.com/robots.txt
のようにサイト名に/robots.txt
を追加したURLで確認できます。
今回は次としました。
User-agent: *
Allow: /
アイコンの作成
以下のサイズの画像を用意して、public フォルダに配置します。
- 180×180 // ファイル名の例:apple-touch-icon.png
- 192×192 // ファイル名の例:icon-192×192.png
- 256×256 // ファイル名の例:icon-256×256.png
- 384×384 // ファイル名の例:icon-384×384.png
- 512×512 // ファイル名の例:icon-512×512.png
- favicon.ico
これをおこなうのに PWA Manifest Generator が便利でした。
具体的には、
- 既に作成済のロゴのsvgファイルからInkscapeにて512×512サイズの
logo.png
を作り、それをPWA Manifest Generatorに次のように指定しました。manifest.zip
が生成されるのでそれを伸張して使います。
apple-touch-icon.png
は作成済のロゴのsvgファイルからInkscapeにて180×180サイズで作ります。- 作成済のロゴのsvgファイルを
fabicon.svg
とします。 - pngから Convertio にて
favicon.ico
に変換。
vite.config.tsの編集
以下のmanifest
の部分は、PWA Manifest Generatorが生成した manifiest.webmanifest
にある内容を元にしていますが、purpose: 'any maskable'
のところを追加していることに注意します。
import { VitePWA } from 'vite-plugin-pwa';
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
VitePWA({
includeAssets: [
'offline.html',
'favicon.svg',
'favicon.ico',
'robots.txt',
'apple-touch-icon.png',
],
manifest: {
theme_color: '#ffffff',
background_color: '#4a90e2',
display: 'standalone',
scope: '/',
start_url: '/',
short_name: '\u305f\u3066\u30c4\u30a4\u30fc\u30c8',
description:
'\u7e26\u66f8\u304d\u30c4\u30a4\u30fc\u30c8\u3092\u3059\u308b\u305f\u3081\u306e\u30c4\u30fc\u30eb\u3002',
name: '\u305f\u3066\u30c4\u30a4\u30fc\u30c8',
icons: [
{
src: '/icon-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/icon-256x256.png',
sizes: '256x256',
type: 'image/png',
},
{
src: '/icon-384x384.png',
sizes: '384x384',
type: 'image/png',
},
{
src: '/icon-512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: '/icon-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
],
},
}),
],
});
index.htmlの編集
OGPの設定は省略しますが、次のようにしてみました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>たてツイート</title>
<meta
name="description"
content="縦書きでツイートするためにテキストを変換します。"
/>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link
rel="alternate icon"
href="/favicon.ico"
type="image/png"
sizes="16x16"
/>
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
<link rel="mask-icon" href="/favicon.svg" color="#FFFFFF" />
<meta name="theme-color" content="#ffffff" />
:
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<!-- PWA -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('./serviceWorker.js')
.then((reg) => console.log('サービスワーカーの登録成功', reg.scope))
.catch((err) => console.log('サービスワーカーの登録失敗', err));
});
}
</script>
</body>
</html>
public/serviceWorke.js の追加
index.html
の script
タグで参照している serviceWorker.js
を次の内容で public
フォルダに配置しました。オフラインのときに表示する offline.html
を指定しています。また、このファイルは vite.config.ts
でも指定しています。
const CACHE_NAME = 'version-1';
const urlsToCache = ['index.html', 'offline.html'];
// Install SW
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
// Listen for requests
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(() => {
return fetch(event.request).catch(() => caches.match('offline.html'));
})
);
});
// Activate the SW
self.addEventListener('activate', (event) => {
const casheWhitelist = [];
casheWhitelist.push(CACHE_NAME);
event.waitUntil(
caches.keys().then((casheNames) =>
Promise.all(
casheNames.map((casheName) => {
if (!casheWhitelist.includes(casheName)) {
return cashes.delete(casheName);
}
})
)
)
);
});
public/offline.htmlの追加
オフラインでキャッシュにない場合は次のような画面を表示するためのHTMLを追加してみました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>たてツイート</title>
<style type="text/css">
body {
display: flex;
flex-direction: column;
background: #00aff9;
height: 100vh;
margin: 0;
color: white;
}
h1 {
margin: 0.8em 3rem;
font: 4em Roboto;
}
p {
margin: 0.2em 3rem;
font: 2em Roboto;
}
</style>
</head>
<body>
<div>
<h1>おっと!!!</h1>
<p>このページはオフラインでは表示できません。</p>
<p><a href="../index.html">ホームページに戻る </a></p>
</div>
</body>
</html>
- Post TagsPWA, React, TypeScript, Vite