2025-11-27...
Next.js + Firebaseで「PVカウンター」
Shuichi Nakayama
サイトの記事がどれくらい読まれているかが分かる「閲覧数(Views)カウンター」を実装しました。 「静的なブログに、動的な数字が表示される」という仕組みは、作っていておもしろかったです。
今回は、技術選定の理由や、コストを抑えるための工夫についてまとめます。
技術選定:なぜFirebase (Firestore) を選んだか?
カウンターを作るにあたり、いくつかのアプローチを検討しました。
- Google Analytics Data API:
- メリット:完全無料。
- デメリット:数字の反映にタイムラグがある。
- Upstash (Redis):
- メリット:設定が爆速で、カウンター機能に特化している。
- デメリット:Googleアカウントとは別に管理が必要になるのが少し手間に感じました。
- Google Cloud Firestore (今回採用):
- メリット:Googleアカウントで一元管理できる。リアルタイム更新が得意。
- デメリット:読み書きの回数で課金されるリスクがある(後述の対策で解決)。
結果として、将来的な拡張性も考慮し、Google Cloudの Firestore を採用しました。
Firebaseの料金と「安心設定」について
Firebaseの**「Sparkプラン(無料)」**を利用することにしました。
- Sparkプランの無料枠:
- 書き込み: 1日 20,000 件まで
- 読み取り: 1日 50,000 件まで
- もし無料枠を超えたら?: 無料枠を超えた時点でAPIが停止するだけで、勝手に課金されることはありません。
実装のおおまかな流れ
実際に機能を追加するまでのステップは以下の通りです。
- Firebaseプロジェクトの作成 Firebaseコンソールでプロジェクトを作成し、ウェブアプリを登録してAPIキーを取得。
- データベース (Firestore) の準備 コンソール上でデータベースを作成します。念のため「テストモード」で開始。
- Next.jsとの連携
でライブラリをインストールし、取得したAPIキーを使って初期化ファイル (npm install firebase
) を作成。lib/firebase.ts - カウンターコンポーネントの作成
数字を表示し、カウントアップ処理を行う
コンポーネントを作成します。ViewCounter - ページへの配置 記事詳細ページにコンポーネントを配置して完成。
コストを抑える実装の工夫
無料枠があるとはいえ、無駄なリクエストは減らしたいので、Next.js 側のコードで以下の工夫をしました。
コンポーネント側で書き込みを制御
「ページを表示しただけでカウントアップ」してしまうと、将来的に一覧ページなどに設置した際、大量の書き込みが発生してしまいます。 そこで、コンポーネントに
countUp というモード切替を持たせ、「意図した場所(詳細ページ)以外では絶対に書き込みを行わない」 設計にしました。
連打対策(sessionStorage)
同じ人がブラウザでリロードを連打しても、カウントが無駄に増えないようにしました。
sessionStorage を使い、「このブラウザではカウント済み」というフラグを管理することで、重複カウントを防いでいます。