Next.jsにPWAを構築する

投稿日
Next.jsにPWAを構築する

Next.jsにPWAを導入する機会があったため、備忘録を兼ねて記載していきます。



導入するにあたり next-pwa というパッケージを利用します。


公式GitHubで「Zero Config PWA Plugin for Next.js」と謳っているだけあり、

かなりお手軽に導入することが出来ました!

Zero config PWA plugin for Next.js, with workbox 🧰
3.8k
316
JavaScript

検証した環境

1 next 14.1.3
2 next-pwa 5.6.0

インストール

パッケージを追加します

npm install next-pwa

初期設定

next-pwaを用いてPWA化を行う初期手順は大きく3つ

  1. manifest.jsonの用意
  2. プロジェクトにmanifest.jsonの追加・設定
  3. next-pwaの設定

manifest.jsonの用意

マニフェストファイルとは、ネイティブアプリのように見せるための情報です

ウェブアプリマニフェストは、ウェブアプリケーションについて、ウェブアプリをダウンロードしたり、ユーザーにネイティブアプリと同じように見せる(例えば、端末のホーム画面にインストールされ、ユーザーに素早いアクセスと豊かな操作性を提供するなどの)ために必要な情報を JSON テキストファイルで提供します

ウェブアプリマニフェスト | MDN より引用



項目としては以下のようなものがあります

メタ情報必須説明
nameアプリケーションの名前
short_nameアプリケーションの短縮名(ホーム画面などで使用)
iconsアプリケーションのアイコンの配列
start_urlアプリケーションが起動するときに最初に開くURL
displayアプリケーションの表示モード(例: fullscreen, standalone
background_color起動画面やスプラッシュ画面の背景色
descriptionアプリケーションの説明文
theme_colorアプリケーションのテーマカラー

私がMac版のchromeで試したところ

  • start_url
  • display

の2つを指定しないとchromeからのアプリ化が出来ないようでした


ホーム画面に追加する(Add to home screen/A2HS)際には更に追加した方が良い項目があるようです

ブラウザショートカットとしてのA2HS #PWA - Qiita





作成する上でアイコンが必須になるので、slackの絵文字ジェネレーターを使って作ってみましたw

絵文字ジェネレーター - Slack 向け絵文字を無料で簡単生成

slackの絵文字ジェネレーターでアイコンを生成

手軽に試せるのでとてもありがたいですね!



PWA manifest Generator

manifest.jsonを手軽に生成出来るサービスがあります!

私が調べた限りパッとで2つほど出てきました



検索で最初に引っかかった、PWA Manifest Generator を使ってみます

アイコンがどう表示されるかも分かる上、必要なファイル群がDLまで出来るので便利ですね ✨



zipファイルの中身には以下のようなファイルが入っています

.
├── icon512_maskable.png
├── icon512_rounded.png
└── manifest.json

DLしたjsonは以下のようになってました

manifest.json
{
  "theme_color": "#8936FF",
  "background_color": "#2EC6FE",
  "icons": [
    {
      "purpose": "maskable",
      "sizes": "512x512",
      "src": "icon512_maskable.png",
      "type": "image/png"
    },
    {
      "purpose": "any",
      "sizes": "512x512",
      "src": "icon512_rounded.png",
      "type": "image/png"
    }
  ],
  "orientation": "any",
  "display": "standalone",
  "dir": "auto",
  "lang": "ja",
  "name": "add PWA for Next.js",
  "short_name": "PWA"
}


必須項目のみ残しつつ、Macのchromeで必要な2つ( start_urldisplay )を追加し書き直します

manifest.json
{
  "name": "add PWA for Next.js",
  "short_name": "PWA",
  "icons": [
    {
      "purpose": "maskable",
      "sizes": "512x512",
      "src": "icon512_maskable.png",
      "type": "image/png"
    },
    {
      "purpose": "any",
      "sizes": "512x512",
      "src": "icon512_rounded.png",
      "type": "image/png"
    }
  ],
  "start_url": "/",
  "display": "standalone"
}

プロジェクトにmanifest.jsonの追加・設定

プロジェクトのpublicフォルダに先ほどのファイルを追加

publicフォルダにmanifest.jsonなどを追加



<head> 内でmanifest.jsonを読み込みます

App Routerを導入している場合、1番ルートで読み込まれる layout.tsx に追記します

app/layout.tsx
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode
}>) {
  return (
    <html lang="en">
    <head>
      <link rel="manifest" href="/manifest.json"/>
    </head>
    <body className={inter.className}>{children}</body>
    </html>
  )
}

next-pwaの設定

Next.jsの設定ファイルを調整します

next.config.js
/** @type {import('next').NextConfig} */
 
const withPWA = require('next-pwa')({
  dest: 'public',
})
 
module.exports = withPWA({
})


dev環境でも確認可能なので

npm run dev

http://localhost:3000 にアクセスすると

PWA化が完了

PWAとしてDL出来るボタンが表示されていれば成功です!



インストールするとアプリのように起動されます🎉

PWA化したアプリが起動出来た

調整

PWA化は確認が出来たので、開発を進める上での設定を2点行います

  1. gitignoreの設定
  2. 開発環境ではPWAを無効に

gitignoreの設定

PWAの設定を行った後に開発環境を起動すると以下のようなファイルが出来ています

  • sw.js
  • workbox-xxx.js
PWA関連の不要なファイルが出来ている


開発環境起動時やビルド時に自動的に生成されるファイル群で特に開発に必要なものではありません


そのためgitignoreに追加します

.gitignore
# next-pwa
**/public/sw.js
**/public/sw.js.map
**/public/workbox-*.js
**/public/workbox-*.js.map

開発環境ではPWAを無効に

開発環境でPWA化を有効にすると以下のようなメッセージが流れます

 ⚠ GenerateSW has been called multiple times, 
 perhaps due to running webpack in --watch mode.
 The precache manifest generated after the first call may be inaccurate!
 Please see https://github.com/GoogleChrome/workbox/issues/1790 for more information.


開発時、ブラウザ確認で問題なければ開発環境でのPWAは無効にしておきます

next.config.js
/** @type {import('next').NextConfig} */
 
const withPWA = require('next-pwa')({
  dest: 'public',
  disable: process.env.NODE_ENV === "development",
})
 
module.exports = withPWA({
})
プロフィール画像
Yuki Takara
都内でフリーランスのエンジニアをやってます。フロントとアプリ開発メインに幅広くやってます。