第10回 人気記事を自動表示する―GA4のPV上位3件をゆまラボのTOPページへ反映
GA4 Data APIの直近30日PVをContent Collectionsの記事と照合し、上位3件をゆまラボのTOPページへ自動表示した。既存ArticleCardを再利用し、PV数や順位は表示しない構成にした。

第9回では、Cloudflareのビルド環境からGA4 Data APIを利用するための認証を用意した。
ローカルではgcloud ADC、Cloudflareでは GA4_ADC_JSON を使える状態になった。
今回は、その認証と第8回で作った記事別PV取得処理をTOPページへ接続する。
目的は、直近30日でアクセスの多い記事を3件だけ「注目コンテンツ」として表示すること。
PV数や順位は画面へ出さず、記事カードだけを人気順に並べる。
修正前はカテゴリの次に新着・更新記事#
修正前のTOPページは、上から次の順になっている。
hero
↓
連載
↓
カテゴリ
↓
新着・更新記事
「人気記事」のような枠はまだ存在しない。

以前から、アクセスデータが蓄積したら「カテゴリ」と「新着・更新記事」の間へ注目コンテンツを追加する予定にしていた。
今回、その部分を実装する。
第8回のGA4取得処理をサイト側でも再利用する#
既存の scripts/ga-pageviews.mjs には、GA4 Data APIから次のデータを取得する処理がある。
- Property:
553074385 - 期間:
30daysAgoからyesterday - dimension:
pagePath - metric:
screenPageViews /blog/前方一致- PV降順
今回、同じAPI問い合わせをTOPページ用にもう1本作るのではなく、共通処理を src/utils/ga4-pageviews.mjs へ切り出した。
変更したファイルは3つ。
src/utils/ga4-pageviews.mjs
scripts/ga-pageviews.mjs
src/pages/index.astro
node scripts/ga-pageviews.mjs から実行できる既存CLIも残したまま、Astro側から同じ取得処理を利用する構成にした。
新しいnpmパッケージは追加していない。
ローカルADCとCloudflare Secretを切り替える#
認証は実行環境によって2経路にした。
ローカル
↓
gcloud Application Default Credentials
Cloudflare
↓
GA4_ADC_JSON
GA4_ADC_JSON が存在する場合はJSONを解析し、authorized_user 形式の認証情報としてGA4クライアントへ渡す。
Secretが存在しないローカル環境では、従来どおりADCへフォールバックする。
これにより、開発時は毎回Cloudflare用のSecretを手元へコピーする必要がなく、第8回までと同じ方法で確認できる。
一方、Cloudflare側ではgcloud CLIを前提にせず、Secretに登録した認証情報を使用する。
認証情報は生成HTMLや画面へ出力しない。
GA4のURLをそのまま人気記事にはしない#
GA4から返る pagePath には、Content Collectionsの記事ではないURLも含まれる。
実際、第9回までの確認では次のような結果があった。
/blog/
/blog/codex-luna-astra-astro-comparison/
/blog/sns-publishing-candidates/
/blog/27-astro-image-optimization-lazy-loading/
...
/blog/ は記事一覧ページなので、人気記事の候補には入れない。
また、GA4にURLが残っていても、現在のContent Collectionsに対応する公開記事が存在しなければカードを作れない。
そこで今回の処理では、GA4の結果をそのまま3件選ぶのではなく、現在のContent Collectionsの記事URLと照合してから候補を決めるようにした。
GA4
pagePath + screenPageViews
↓
/blog/ を除外
↓
Content Collectionsの記事URLと照合
↓
一致した記事だけ残す
↓
人気順に並べる
↓
上位3件
タイトル、description、heroImage、公開日などの表示情報はGA4から作らず、Astroの記事データを使う。
GA4は「どの記事がよく読まれたか」を決めるためだけに使用する。
同じPVならpagePathの昇順にする#
実データでは、3位付近に同じPVの記事が複数あった。
今回確認した時点では、次の2記事がどちらも30PVで並んだ。
/blog/27-astro-image-optimization-lazy-loading/
/blog/technical-blog-monetization/
同率時の順番が毎回曖昧にならないよう、ソート条件を固定した。
1. screenPageViews DESC
2. pagePath ASC
まずPVの多い順。
PVが同じなら pagePath の昇順。
この順序で並べた後、Content Collectionsと一致する記事の先頭3件を採用する。
実際に選ばれた3記事#
実装後に選ばれた記事は次の3件。
| 記事 | pagePath | screenPageViews |
|---|---|---|
| CodexでAstro改修をLunaとAstraに任せて比較―小さな改修に高性能モデルは必要なのか? | /blog/codex-luna-astra-astro-comparison/ | 66 |
| 記事をSNSへ流す運用を始める―X連携の前に投稿方法と候補を確認する | /blog/sns-publishing-candidates/ | 38 |
| 第27回 画像表示を見直す―Astroの画像最適化と遅延読み込みでページを軽くする | /blog/27-astro-image-optimization-lazy-loading/ | 30 |
このPV数は確認用のデータで、TOPページには表示しない。
「1位」「2位」「3位」の順位表示も付けていない。
読者から見ると、通常の記事カードが3件並ぶだけになる。
既存のArticleCardをそのまま使う#
注目コンテンツ専用の新しい記事カードは作らなかった。
既存の ArticleCard.astro を再利用した。
これにより、TOPページの新着記事や他の一覧と同じ形式で、次の情報を表示できる。
- カテゴリ・サブカテゴリ
- 公開日
- アイキャッチ
- 記事タイトル
人気記事用だけ別のカードデザインを持たせると、同じ記事を表示するためのUIが増えてしまう。
今回は「人気順で3件選ぶ」というデータ側だけを追加し、カード側は既存のものを使う形にした。
カテゴリと新着・更新記事の間へ追加#
src/pages/index.astro へ「注目コンテンツ」を追加した。
変更後は、この順番になった。
hero
↓
連載
↓
カテゴリ
↓
注目コンテンツ
↓
新着・更新記事
見出しの横には「アクセスの多い記事」と補足を入れている。
3件のカードにはPV数や順位を出していないため、既存TOPの見た目から大きく外れない。

実際の画面では、カテゴリの直後に3枚のカードが並び、その下にこれまでどおり「新着・更新記事」が続く。
CLIでも82記事を取得できた#
実装後も既存CLIを実行した。
node scripts/ga-pageviews.mjs
結果は成功し、今回の条件では82記事が対象になった。
前段階では /blog/ を含む83件が取得されていたが、今回の人気記事処理では記事一覧ページを対象外にしている。
GA4_ADC_JSON を使う認証経路でもGA4取得に成功した。
ローカルADCとCloudflare用Secretの両方を同じGA4取得処理へ接続できた。
npm run buildも成功#
続けてAstroのビルドを実行した。
npm run build
結果は成功。
確認できた内容は以下。
- 237ページ生成
- 内部リンク9649件
- リンクエラー0件
- TOPページに注目コンテンツ3件を生成
- PV数をHTMLへ出力していない
- Secret情報をHTMLへ出力していない
既存の新着・更新記事もそのまま残っている。
今回の変更では、API取得に失敗した場合は既存CLIと同じくビルドを失敗させる仕様にした。取得失敗時だけ古いランキングを残すキャッシュ処理などは追加していない。
人気記事はビルド時に更新される#
今回の構成では、GA4 Data APIをAstroのビルド時に呼び出す。
そのため、TOPページの「注目コンテンツ」はブラウザを開くたびにGA4へ問い合わせるわけではない。
Cloudflareでビルド
↓
GA4 Data APIから直近30日を取得
↓
人気記事3件を決定
↓
AstroがTOPページを生成
↓
静的HTMLとして配信
次のビルドが実行されるまで、表示される3件はそのままになる。
リアルタイムランキングではなく、デプロイ時点の直近30日データを使った「注目コンテンツ」として扱う。
変更したファイルと役割#
今回の変更は、TOPページの人気記事表示に必要な範囲だけに絞った。
src/utils/ga4-pageviews.mjs
GA4取得と認証の共通処理
scripts/ga-pageviews.mjs
既存CLIから共通処理を利用
src/pages/index.astro
Content Collectionsとの照合
人気記事3件の決定
注目コンテンツの表示
新規npmパッケージは追加していない。
既存URL、カテゴリ、連載、タグ、RSS、sitemap、robots.txt、GA4計測タグも変更していない。
これで、第3回で「将来はGA4のデータから人気記事を自動表示する」と決め、第4回でGA4を導入し、第8回でData APIから記事別PVを取得した流れが、TOPページの表示までつながった。


