Next.js (TypeScript) プロジェクトをPWA化

2022-01-20

Next.js (TypeScript) のプロジェクトをPWA化したのですが、忘れないうちにやり方をメモっておきます。

方法

next-pwa を使いました。

iOSSafari限定で「ホーム画面に追加」からおこないます。

詳細

パッケージのインストール

$ yarn add next-pwa
又は
$ npm i next-pwa

src\pages\_document.tsx の編集

次のように設定します。

import NextDocument, { Html, Head, Main, NextScript } from 'next/document'
import React from 'react'

type Props = {}

class Document extends NextDocument<Props> {
  render() {
    return (
      <Html lang='ja'>
        <Head />
        <link rel='manifest' href='/manifest.json' />
        <link rel='apple-touch-icon' sizes='180x180' href='/apple-touch-icon.png' />
        <meta name='application-name' content='バス時刻表' />
        <meta name='apple-mobile-web-app-capable' content='yes' />
        <meta name='apple-mobile-web-app-status-bar-style' content='default' />
        <meta name='apple-mobile-web-app-title' content='バス時刻表' />
        <meta name='description' content='武蔵村山製作所勤務者のためのバス時刻表' />
        <meta name='theme-color' content='#fff' />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default Document

tsconfig.json の include に”src/pages/_document.tsx” がなければ追加します。

next.config.js の編集

次のように設定します。

/** @type {import('next').NextConfig} */

const withPWA = require('next-pwa');

module.exports = withPWA({
  reactStrictMode: true,
  pwa: {
    dest: 'public',
    register: true,
    disable: process.env.NODE_ENV === 'development',
  },
});

開発環境で service worker のデバッグするつもりがないので、disable を開発環境で true にしています。

画像の用意

以下のサイズの画像を用意して、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

これをおこなうのに PWA Manifest Generator が便利でした。

manifest.json の編集

{
    "theme_color": "#f69435",
    "background_color": "#f69435",
    "display": "standalone",
    "scope": "/",
    "start_url": "/",
    "name": "\u30d0\u30b9\u6642\u523b\u8868",
    "description": "\u6b66\u8535\u6751\u5c71\u88fd\u4f5c\u6240\u52e4\u52d9\u8005\u306e\u305f\u3081\u306e\u30d0\u30b9\u6642\u523b\u8868",
    "short_name": "\u30d0\u30b9\u6642\u523b",
    "icons": [
        {
            "src": "/icon-192x192.png",
            "sizes": "192x192",
            "type": "image/png",
            "purpose": "any maskable"
        },
        {
            "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"
        }
    ]
}

namedescriptionは、PWA Manifest Generator が生成したUnicodeです。これをデコードするには、 Unicodeエスケープシーケンス変換ツールが利用できました。

.gitignore の編集

以下を追加して、自動的に生成されるファイルをgitで管理しないようにする。

# PWA files
**/public/sw.js
**/public/workbox-*.js
**/public/worker-*.js
**/public/sw.js.map
**/public/workbox-*.js.map
**/public/worker-*.js.map