2025-11-27...

Next.js + Firebaseで「PVカウンター」

Shuichi Nakayama
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が停止するだけで、勝手に課金されることはありません。

実装のおおまかな流れ

実際に機能を追加するまでのステップは以下の通りです。

  1. Firebaseプロジェクトの作成 Firebaseコンソールでプロジェクトを作成し、ウェブアプリを登録してAPIキーを取得。
  2. データベース (Firestore) の準備 コンソール上でデータベースを作成します。念のため「テストモード」で開始。
  3. Next.jsとの連携
    npm install firebase
    でライブラリをインストールし、取得したAPIキーを使って初期化ファイル (
    lib/firebase.ts
    ) を作成。
  4. カウンターコンポーネントの作成 数字を表示し、カウントアップ処理を行う
    ViewCounter
    コンポーネントを作成します。
  5. ページへの配置 記事詳細ページにコンポーネントを配置して完成。

コストを抑える実装の工夫

無料枠があるとはいえ、無駄なリクエストは減らしたいので、Next.js 側のコードで以下の工夫をしました。

コンポーネント側で書き込みを制御

「ページを表示しただけでカウントアップ」してしまうと、将来的に一覧ページなどに設置した際、大量の書き込みが発生してしまいます。 そこで、コンポーネントに

countUp
というモード切替を持たせ、「意図した場所(詳細ページ)以外では絶対に書き込みを行わない」 設計にしました。

連打対策(sessionStorage)

同じ人がブラウザでリロードを連打しても、カウントが無駄に増えないようにしました。

sessionStorage
を使い、「このブラウザではカウント済み」というフラグを管理することで、重複カウントを防いでいます。