背景
Next.js で next-pwa
を用いて PWA に対応させつつ、 ブラウザへ送ったプッシュ通知を受信して表示させる方法でちょっと詰まりました。というのも、next-pwa
で自動生成されるサービスワーカーのスクリプトと、プッシュ通知を受信して表示させるためのサービスワーカーのスクリプトを共存させる方法が分からなかったためです。
next-pwa
の GitHub に解決策が書かれていたので備忘録としてまとめておきます。
next-pwa を用いた PWA への対応
下記のような設定で、 next-pwa
を利用します。
const withPWA = require('next-pwa')({ // next-pwa を読み込む
dest: 'public',
register: true,
skipWaiting: true,
});
const withTM = require('next-transpile-modules')([
'hogehoge',
'fugafuga',
]);
const { i18n } = require('./next-i18next.config');
module.exports = withTM(
withPWA({ // ここに記述
reactStrictMode: true,
i18n,
images: {
domains: [
'somewhere',
'localhost',
],
},
webpack: (config) => {
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'],
});
return config;
},
async redirects() {
return [
{
source: '/test/some',
destination: '/',
permanent: false,
},
];
},
experimental: {
scrollRestoration: true,
optimizePackageImports: ['@mui/icons-material'],
esmExternals: false,
},
eslint: {
ignoreDuringBuilds: true,
},
}),
);
このように記述してビルドすると、public
配下に workbox-***.js
というスクリプトと sw.js
というサービスワーカーのスクリプトが自動生成されます。
プッシュ通知の受信
web-push
を用いたプッシュ通知の送信方法については長くなるので割愛します。
自分でサービスワーカーのスクリプトを書きます。
// プッシュ通知(web-push)受信時の処理
self.addEventListener('push', function (event) {
const data = event.data.json();
const title = data.title || '新しいアクションがありました';
const options = {
body: data.body || '詳細はクリックして確認してください',
icon: '/test-192x192.png',
badge: '/test-192x192.png',
data: {
url: data.url,
},
};
event.waitUntil(self.registration.showNotification(title, options));
});
// プッシュ通知(web-push)クリック時の処理
self.addEventListener('notificationclick', function (event) {
event.notification.close();
event.waitUntil(
clients.matchAll({ type: 'window', includeUncontrolled: true }).then(() => {
if (clients.openWindow) {
return clients.openWindow(event.notification.data.url);
}
}),
);
});
最初はこのスクリプトを public
配下に置いていましたが、同じスコープに2つのサービスワーカーが共存するような形になって上手くいきませんでした。
そのため、下記を参考にしました。
custom-worker を設置する
It demonstrates how to add custom worker code to the service worker generated by workbox.
(workbox が生成するサービスワーカーにカスタムワーカーコードを追加する方法を示します。)
結論、next.config.js
がある階層に worker/index.js
を作成し、先ほどの service-worker.js
の中身をそこに書くだけでした。
これで PWA とプッシュ通知の表示を両立させることができ、無事に iOS で「ホーム画面に追加」したアプリにてプッシュ通知を受け取ることができました。