genko.meDocs

PV(ページビュー)

サイトのページとCMSの記事に紐づく閲覧数を、genkoで確認するための設定と実装。

自分のサイトのページビューを計測し、genkoのワークスペースで確認できます。ページのパスだけでなく、CMSの記事に紐づく閲覧数を集計できるため、どの記事が読まれているかを確認できます。

管理画面では「メディア」の隣にある「PV」を開きます。コンテンツ一覧にも、文字数の下に記事ごとの閲覧数が表示されます。

受付ドメインを登録する

「PV」で計測を受け付けるドメインを登録します。登録・変更はオーナーまたはメンテナーが行います。登録できるのは最大20件で、サブドメインは別々に登録します。登録外のドメインからの閲覧と、localhostからの閲覧は計測しません。

レイアウトにPageViewを置く

Next.js App Routerでは@genko-me/react/nextからimportします。レイアウトに1つ置くと、各ページのパスを数えます。画面には何も描画しません。

app/layout.tsx
import type { ReactNode } from "react";import { PageView } from "@genko-me/react/next";
export default function RootLayout({ children }: { children: ReactNode }) {  return (    <html lang="ja">      <body>        {children}        <PageView workspace="your-workspace" />      </body>    </html>  );}

workspaceにはワークスペースのスラッグを指定します。APIキーは不要です。最初の閲覧が届くと、管理画面は設定手順からグラフへ切り替わります。受信状況は10秒ごとに確認します。動作確認には登録済みドメインのサイトを使ってください。

記事ページでも数える

記事ページには、取得した記事のidを渡して追加します。これは記事の閲覧数だけを加算します。レイアウトで数えたパスを二重に数えることはありません。記事の閲覧数はワークスペース内の公開IDで集計するため、異なるAPIに同じIDの記事がある場合は同じ閲覧数を共有します。

tsx
import { PageView, ViewCount } from "@genko-me/react/next";
export function ArticleViews({ entry }: { entry: { id: string } }) {  return (    <>      <PageView workspace="your-workspace" entryId={entry.id} />      <ViewCount workspace="your-workspace" entryId={entry.id} />    </>  );}

Reactとルーター

Next.js以外のReactでは@genko-me/reactからimportします。pathを省略するとlocation.pathnameを使い、戻る・進むのpopstateに追従します。独自のルーターでは現在のパスをpathへ渡してください。値が変わるたびに送信します。

tsx
import { PageView } from "@genko-me/react";
export function SitePageViews({ pathname }: { pathname: string }) {  return <PageView workspace="your-workspace" path={pathname} />;}

Next.js版はusePathname()に追従するため、App Routerの画面遷移でも送信します。Vue・Svelte・Web Components用の部品は今後対応予定です。それまでは後述のJavaScript関数を使えます。

閲覧数を表示する

ViewCountは累計の表示専用で、閲覧数を加算しません。entryIdで記事、pathでページの累計を指定します。両方を渡すとentryIdが優先されます。

tsx
import { ViewCount } from "@genko-me/react";
export function ArticleCount({ entryId }: { entryId: string }) {  return (    <ViewCount      workspace="your-workspace"      entryId={entryId}      format={count => `${count.toLocaleString("ja-JP")} 回閲覧`}      fallback={<span>—</span>}    />  );}

パス別なら<ViewCount workspace="your-workspace" path="/blog/hello" />を使います。累計は最大約5分キャッシュされるため、表示には少し遅れがあります。

prop対象使い方
workspace両方ワークスペースのスラッグ。React版では必須
baseUrl両方省略時はhttps://api.genko.me
entryId両方記事の公開ID
path両方PageViewでは省略時に現在のパス。ViewCountでは表示対象のパス
formatViewCount数値を受け取り、表示するReactNodeを返す関数
fallbackViewCount取得前・取得失敗時の表示。省略時は何も表示しない
localeViewCount桁区切りのロケール。既定はja-JP
classNameViewCount表示するspanのCSSクラス

Next.js版はサーバーコンポーネントから使い、workspaceの代わりにList・Viewと同じapi={client.blog}も指定できます。ブラウザにAPIキーは渡りません。Next.js版のViewCountはcacheで取得結果を再利用する秒数を指定でき、既定は300です。formatを使う場合もサーバー側で指定します。

JavaScriptや他のフレームワークで使う

ブラウザでページを表示したときにsendPageViewを呼びます。SPAではルーターの遷移後にも呼んでください。

ts
import { sendPageView } from "@genko-me/core/browser";
sendPageView({ workspace: "your-workspace", path: location.pathname });// 記事ページでは記事の回数を別に加算します。sendPageView({ workspace: "your-workspace", entryId: "abcDEF123456" });

累計の取得にはfetchViewCountsを使います。これはサーバー側でも使え、失敗時は例外を投げます。

ts
import { fetchViewCounts } from "@genko-me/core";
const counts = await fetchViewCounts({  workspace: "your-workspace",  entryIds: ["abcDEF123456"],  paths: ["/blog/hello"],});console.log(counts.entries.abcDEF123456, counts.paths["/blog/hello"]);

よく読まれている順に並べる

配信一覧のorders="-views"は累計閲覧数の多い順、orders="views"は少ない順です。未計測の記事は0として扱います。

tsx
import { List, ListItem } from "@genko-me/react/next";import { client } from "@/lib/client";
export default function PopularArticles() {  return (    <List api={client.blog} orders="-views" limit={4} href="/blog/{id}">      <h2><ListItem id="title" /></h2>    </List>  );}

SDKでもgenko.apis.blog.list({ orders: "-views", limit: 4 })を使えます。APIごとの累計と直近の集計は、認証付きのGET /v1/{workspace}/_views/{endpoint}?ids=a,b&days=30で取得できます。SDKではgenko.apis.blog.views({ ids: ["abcDEF123456"], days: 30 })を使います。低レベルクライアントにはclient.getViews(...)があります。詳しくはSDKリファレンスを参照してください。HTTPの入力・レスポンスは配信APIに記載しています。

計測と保存のルール

同じ端末から同じページへの閲覧は、30分に1回として数えます。IPアドレスとUser-Agentから日ごとに変わるソルト付きハッシュを作り、一時的な重複判定に使います。IPアドレスとUser-Agentそのものは保存しません。

保存する閲覧データは、ページのパスごと・記事ごとの日別回数だけです。パスのクエリとハッシュは取り除き、連続するスラッシュと末尾のスラッシュも正規化します。Cookieは使いません。リファラー・デバイス・国・訪問者の追跡情報も保存しません。

ボットや自動操作ブラウザ(navigator.webdriver)は計測せず、IPごとのレート制限もあります。送信はsendBeaconとtext/plainを使うためCORSプリフライトが不要で、利用できない場合はfetchへ切り替えます。送信の失敗はサイトの表示に影響しません。公開エンドポイントの仕様は配信APIを参照してください。

サイトのプライバシーポリシーには、ページのパスをgenko(genko.me)へ送信することを記載するとよい場合があります。

料金

計測は現在無料です。今後の無料枠と従量料金は未定です。

最終更新: 2026年10月19日

目次