モバイル アプリは、ユーザーに必要なサービスを迅速かつ簡単に提供できるため、企業にとってほぼ不可欠なものとなっています。しかし、Web 上でモバイル アプリのようなエクスペリエンスを実現できるとしたらどうでしょうか。これがプログレッシブ ウェブ アプリ (PWA) の目的です。
Top Design Firms の調査で示されているように、モバイル アプリの需要は高まっています。2021 年には 3 分の 1 (32%) でしたが、2022 年には中小企業のほぼ半数 (48%) がモバイル アプリを導入しました。この傾向は、すべてのプラットフォームでモバイルのようなインタラクションを求めるユーザー ニーズの変化を示しています。
PWAを開発することで、企業はWebブラウザ経由でネイティブアプリのエクスペリエンスを直接提供することができ、エンドユーザーに別のモバイルアプリケーションを必要とせずに信頼性が高く魅力的なアプリケーションを提供することができます。
プログレッシブ ウェブ アプリは、Android から iOS、デスクトップまでさまざまなプラットフォーム固有の考慮事項を考慮して構築する必要なく、モバイル デバイスと同様のネイティブ サポートをユーザーに提供するアプリです。軽量で、すべてのデバイスからアクセスでき、インターネットに接続すると自動的に更新されます。
最近、NextJs アプリを Progressive Web App にするための最善の方法を調査していたところ、PWA のネイティブ サポートを含む最近の Next.js アップデートに関する以下の Reddit のコメントを見つけました。
こちらのコメントをご覧ください。
アップデートを確認した後、PWA の作成がこれまでになく簡単になったと断言できます。それを証明します。
PS: アプリを PWA として認識させるには、マニフェスト ファイルとサービス ワーカー ファイルという 2 つのファイルが非常に重要です。
npx create-next-app@latest my-pwa-app
または
yarn create next-app my-pwa-app
コマンドを実行した後、インストールの詳細に関するプロンプトに従ってプロジェクトディレクトリに移動します。
cd my-pwa-app
開発サーバーを起動する
npm run dev
app
ディレクトリにmanifest.json
またはmanifest.ts
ファイルを作成します。
import type { MetadataRoute } from 'next' export default function manifest(): MetadataRoute.Manifest { return { name: 'Next.js PWA', short_name: 'NextPWA', description: 'A Progressive Web App built with Next.js', start_url: '/', display: 'standalone', background_color: '#ffffff', theme_color: '#000000', icons: [ { src: '/icon-192x192.png', sizes: '192x192', type: 'image/png', }, { src: '/icon-512x512.png', sizes: '512x512', type: 'image/png', }, ], } }
standalone
minimal-ui
fullscreen
、 browser
のいずれかになります。src
、 size
、 type
を指定します。PWA では、少なくとも192x192
と512x512
のサイズのアイコンを用意することが重要です。マニフェストジェネレータのようなウェブサイトを使用すると、マニフェストファイルとさまざまなサイズのアイコンをすばやく生成できます。
サービスワーカーはプッシュイベントをリッスンし、プッシュ通知のために以下の機能を実行します。
self.addEventListener("push", function (event) { if (event.data) { const data = event.data.json(); const options = { body: data.body, icon: data.icon || '/icon.png', badge: "/icons/timer-icon-144.png", vibrate: [100, 50, 100], data: { dateOfArrival: Date.now(), primaryKey: "5", }, }; event.waitUntil(self.registration.showNotification(data.title, options)); } }); self.addEventListener("notificationclick", function (event) { console.log("Notification click received."); event.notification.close(); event.waitUntil(clients.openWindow("<https://your-website.com>")); //This should be the url to your website });
サービス ワーカーを登録するには、サービス ワーカーが作成されるルートを指定する必要があります。
const registration = await navigator.serviceWorker.register("/sw.js", { //provide the route to the service worker scope: "/", updateViaCache: "none", });
通知とサブスクリプションを処理するためにWebプッシュをインストールする
npm install web-push --save
次に、ユーザーがサブスクリプションを持っている場合はそれを取得するか、ユーザーがイベントをプッシュするようにサブスクライブする必要があります。実際のアプリケーションでは、このサブスクリプションは保存のためにサーバーに送信する必要があります。
async function registerServiceWorker() { const registration = await navigator.serviceWorker.register("/sw.js", { scope: "/", updateViaCache: "none", }); const sub = await registration.pushManager.getSubscription(); if (sub) { setSubscription(sub); //This would be sent to a server } else { const pushSubscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY, // Your VAPID public key }); setSubscription(pushSubscription); } }
VAPID キーを生成するには、次のコマンドを実行します。
npx web-push generate-vapid-keys
プッシュ通知をテストする機能を備えたUIをまとめる
"use client"; import { useEffect, useState } from "react"; const Home = () => { const [subscription, setSubscription] = useState<PushSubscription | null>( null ); useEffect(() => { if ("serviceWorker" in navigator && "PushManager" in window) { registerServiceWorker(); } }, []); async function registerServiceWorker() { const registration = await navigator.serviceWorker.register("/sw.js", { //provide the route to the service worker scope: "/", updateViaCache: "none", }); const sub = await registration.pushManager.getSubscription(); if (sub) { setSubscription(sub); //This would be sent to a server } else { const pushSubscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY, // Your VAPID public key }); setSubscription(pushSubscription); } } //Create a function to test the notification const handleSendNotification = async () => { await fetch("/api/sendNotification", { method: "POST", body: JSON.stringify({ message: "Your timer has completed!", subscription: subscription, // This ideally, should not be included in the body. It should have already been saved on the server }), headers: { "Content-Type": "application/json", }, }); }; return ( <div> <h1>My PWA with Push Notifications</h1> <button onClick={handleSendNotification}>Notify Me!</button> </div> ); }; export default Home;
app
ディレクトリ内に、 api
という新しいフォルダーを作成します。api
フォルダー内に、 sendNotification
という名前の別のフォルダーを作成します。sendNotification
フォルダー内に、 route.ts
という名前のファイルを作成します。
構造は次のようになります
app/ └── api/ └── sendNotification/ └── route.ts
route.tsファイルに次のコード行を追加します。
import { NextResponse } from "next/server"; import webpush from "web-push"; webpush.setVapidDetails( "mailto:[email protected]", // Your email process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!, process.env.VAPID_PRIVATE_KEY! ); export async function POST(req: Request) { const { message, subscription } = await req.json(); if (!subscription) { return NextResponse.json( { error: "No subscription available" }, { status: 400 } ); } try { await webpush.sendNotification( subscription, JSON.stringify({ title: "Notification", body: message }) ); return NextResponse.json({ success: true }); } catch (error) { console.error("Error sending notification:", error); return NextResponse.json( { error: "Failed to send notification" }, { status: 500 } ); } }
アプリが PWA になったことを確認するには、ダウンロード アイコンが URL バーの右端に表示されます。また、アプリケーション タブで Web マニフェストに関する情報を確認することもできます。
Next.js の最近のアップデートではネイティブ PWA がサポートされ、プログレッシブ ウェブ アプリの作成プロセスが非常にシームレスになりました。Next.js を使用すると、開発者はユーザーが期待するネイティブのような機能を備えたアプリケーションをすべてウェブ ブラウザー内からすばやく作成できるため、PWA の開発と展開は現代のウェブ開発の一部として簡単なプロセスになりました。