Google Search Console API、インプレッションが 0 になる罠:sc-domain と URL マッピングで詰まった話

GSC API でインプレッションが 0 になる。API は正常なのにデータが返らない——その原因は sc-domain プロパティのサブドメイン混入と、カスタム投稿タイプの URL マッピング不一致にありました。検証済みの 2 件に絞って再現と対処をまとめます。

広告ここから
広告ここまで

目次

    GSC API でデータを取得する実装をしました。コードは動いている。レスポンスも返ってくる。なのに、インプレッションが 0。クリックも 0。ずっと 0 のままでした。

    「API の呼び出し方が間違っているのか」「権限の問題か」と調べ続けて、最終的にわかったのは、GSC API が返すデータは正常だったということです。問題は クエリに渡す URL の組み立て方 にありました。

    今回詰まった原因は 2 つです。どちらも「API は正しく動いているのにデータが 0 になる」タイプの罠で、エラーが出ないぶん発見が遅れます。同じ実装をする人が同じ場所で止まらないよう、再現と対処をまとめておきます。

    1. sc-domain: プロパティはサブドメインの行も返す

    何が起きたか

    Google Search Console には、プロパティの登録形式が 2 種類あります。https://wp-kyoto.net/ のように URL で指定する「URL プレフィックスプロパティ」と、sc-domain:wp-kyoto.net のように指定する「Domain プロパティ」です。

    Domain プロパティは、サブドメインを含むすべてのトラフィックを一括で計測できる便利な形式です。ただし Search Analytics API でクエリすると、サブドメイン(remoneko.wp-kyoto.net など)の行も一緒に返ってきます

    ここで効いてくるのが API の仕様です。Search Analytics API はクリック数の降順で上位の行を優先して返し、rowLimit を超える分は切り捨てます。全行を返す保証はありません。つまり dimensions: ['page', 'query']rowLimit: 100 で取得すると、上位 100 行の大半がサブドメインで埋まり、見たかったメインドメインの行が 1 件も入ってこない、という状態が起きます。

    フィルタなしだと、上位 100 行の多くがサブドメインで占められ、メインドメインの行はごく一部しか拾えませんでした。後述のフィルタを足すと、100 行すべてがメインドメインの行になりました。

    対処法

    dimensionFilterGroupsincludingRegex オペレータのフィルタを追加し、メインドメインの URL だけに絞り込みます。

    dimensionFilterGroups: [{
      filters: [{
        dimension: 'page',
        operator: 'includingRegex',
        expression: `^${publicSiteUrl}/`,  // 例: ^https://wp-kyoto.net/
      }]
    }]

    includingRegexquerypage の dimension に対して使えるオペレータです。正規表現 ^https://example.com/ は先頭一致なので https://sub.example.com/ にはマッチしません。^ による先頭固定と末尾の / の組み合わせで、サブドメインの行を除外できます。

    Domain プロパティを API から叩くときは、最初から page dimension のフィルタをセットで書いておくのが安全だと考えています。

    2. postTypeUrlMappings を未設定にすると WordPress API パスがそのまま使われる

    何が起きたか

    revtrona.comstripe カスタム投稿タイプについて、URL マッピングの設定を省いていました。その結果、フォールバック処理が動き、WordPress REST API のエンドポイント名(rest_base)をそのまま公開 URL として使っていました。

    WordPress API のリンク:  https://wp-kyoto.net/stripe/receptray-app/
    生成された URL(間違い):  https://revtrona.com/stripe/receptray-app/
    実際のサイト URL:          https://revtrona.com/blogs/receptray-app

    /stripe//blogs/ でパスが完全に異なるため、照合は全件 0 件でした。GSC には /blogs/... でインデックスされているのに、こちらは /stripe/... で問い合わせていたので、当然データは返りません。

    原因

    WordPress のカスタム投稿タイプを登録するときに rest_base で指定するエンドポイント名と、フロントエンドサイトの URL パスが一致するとは限りません。REST API 側は stripe、公開サイト側は blogs、というケースは普通にあります。ここを明示的に設定しないと、サイレントに 0 件レポートが続きます。エラーは出ないので、設定漏れに気づきにくいのが厄介な点です。

    対処法

    正しいパスを明示的に設定します。今回は DynamoDB の postTypeUrlMappings に以下を追加しました。

    [
      {
        "postType": "stripe",
        "publicUrlPath": "/blogs/{slug}",
        "identifierType": "slug"
      }
    ]

    修正後、大半の URL が GSC と一致しました。一致しなかったものは、記事が新しくトラフィックがないため GSC 側にデータがないだけで、URL の問題ではありません。

    WordPress でカスタム投稿タイプを使う場合、全投稿タイプに対して明示的にマッピングを定義しておく ことをおすすめします。rest_base と公開パスがたまたま一致しているケースもありますが、それに頼ると、ずれた瞬間に静かに 0 件になります。

    まとめ

    # サイト 原因 対処
    1 wp-kyoto.net sc-domain: がサブドメインを含み、上位行(rowLimit)を圧迫する includingRegex フィルタでメインドメインに限定
    2 revtrona.com postTypeUrlMappings 未設定で rest_base のパスが使われ不一致 正しい公開パスを明示的にマッピング

    2 件とも、GSC API が返すデータは正常でした。0 になる原因は API ではなく、クエリに渡す URL の組み立て方 にあります。

    「データがない」と「データを取れていない」は違います。GSC API でインプレッションが 0 になったら、まず照会している URL が本当に GSC に存在する形になっているかを確認するのが、いちばん早い切り分けです。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark