Next.js v9+でPWAに対応させる


はじめに

Next.jsで簡単にPWAに対応させることができると言う文献をいくつか見たので勉強がてら実際にやってみました。
たくさんハマりましたが最終的にたどり着いたので共有したいと思います。

※ NuxtじゃなくてNextです。

環境

  • Next.js v10.0.3

結論

Next.js(v9)以上の場合、next-offlineよりnext-pwaのほうが簡単

方法

1. アイコン & public/manifest.jsonを作成

https://qiita.com/shisama/items/d4d0b24980beaea57231
これを参考に作成しました。

注)アイコンのどれか一つにmaskable iconを指定してあげなければいけません。
もしもmaskable iconが指定されていない場合、android端末ではアイコンの周りが白色になってしまいますが、maskable iconが指定されていると、枠いっぱいにアイコンを表示させることができます。
https://web.dev/maskable-icon-audit/?utm_source=lighthouse&utm_medium=devtools

2. Headタグに追加

以下を追加します

  • 「1.」で作成したmanifest.json
  • theme-color
  • apple-touch-icon
// pages/_document.tsx
class CustomDocument extends Document {
  render(): JSX.Element {
    return (
      <Html lang="ja-JP">
        <Head>
          <link rel="manifest" href="/manifest.json" />
          <meta name="theme-color" content="#68d391" /> {/*  好きな色を入力 */}
          <link{/*  アイコンを選択 */}
            rel="apple-touch-icon"
            sizes="180x180"
            href="/icon-192x192.png"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}
export default CustomDocument;

3. next.config.jsに以下を追加

https://github.com/shadowwalker/next-pwa/tree/master/examples/next-9
まさにここを見て実装すると一瞬なのですが、next.config.jsに

const withPWA = require('next-pwa')

module.exports = withPWA({
  pwa: {
    dest: 'public'
  }
})

と入力するだけ。

chromeの右上の三点リーダーをクリックして、
「**」をインストール...
と表示されると成功です。

備考

Next.js v9以上から/publicから静的ファイルを取得することができるのでそれらの静的ファイルを提供するためだけのカスタムサーバーを記述する必要がなくなったためにnext-pwaでは簡単に実装できるそうです。
https://github.com/shadowwalker/next-pwa/tree/master/examples/next-9)

 (番外編)next-offlineを使ってPWAを適応させようとしてみましたが、、

next-pwaではなく、next-offlineを使ってPWAを実現する方法を調べたところ、自前でカスタムサーバーを記述する必要があり、server.jsを追加しなければいけないとのことでした。
しかし、Next.jsのリファレンスによると、

A custom server will remove important performance optimizations, like serverless functions and Automatic Static Optimization.

server.jsを追加しカスタムサーバーを記述するとSSGができなくなることがあるそうです。

さらに個人的にローカル開発環境でssl接続ができず、next-offlineではPWAが確認できなかったため、next-offlineでのPWAを断念しました。

参考文献