ホームGatsbyGatsbyブログで人気記事一覧を表示する方法。
2020年6月24日

Gatsbyブログで人気記事一覧を表示する方法。

google

10月28日追記
Gatsbyブログについて、初noteを書きました。
【完全版】爆速GatsbyでWordPressちっくなブログを作る全手順

こんにちは、筋肉めがねです。

Gatsbyブログに人気記事一覧を追加したい。
どうやらGoogle Analyticsの記事毎の閲覧数データを使えるっぽい。
Google APIで引っ張ってこれるらしいけど、どう実装するの?

そんな方へ向けて、Gatsbyブログで人気記事一覧を表示する方法を解説します。 Google APIのGoogle Analytics APIを使います。

Gatsbyで人気記事一覧を取得するプロセスの概要

人気記事とは

ご存知だとは思いますが、「人気記事」、もしくは「よく読まれている記事」というタイトルで、あらゆるブログのサイドバーに見かける一覧ですね。

popular list

人気記事一覧を取得する流れ

  • Google Analyticsをブログに設置します。記事毎のアクセス数の取得。
  • Google APIで、AnalyticsのデータをGatsbyブログへ連携する。
  • アクセス数でソートした記事一覧をブログのサイドバーに表示する。

人気記事一覧を取得する流れは上のようになっています。

人気記事一覧を取得するには、記事毎のアクセス数を知る必要があります。

そこで、アクセスデータをGoogle APIを使ってGoogle Analyticsから引っ張ってくる必要があります。

そして、アクセス数が多い順に記事をソートして、サイドバーへ載せる、というプロセスです。

それでは、見ていきましょう。

前提条件(Google Analyticsの設定)

Google Analytics APIを使うためには、Google AnalyticsがGatsbyに導入されている必要があります。

Google Analyticsの導入方法をこちらを参照ください。
Gatsby + Netlifyのブログに、Google Analyticsを導入しました。

Google APIキーをGoogle Cloud Platformで取得する

先ずはGoogle APIキーを取得する必要があります。

これはGoogle Cloud Platform(GCP)で設定します。

もし、GCPのアカウントが無い場合は、アカウントを作ります。

プロジェクトの作成

GCPのアカウントを作成したら、APIキーを取得していきますが、そのために、GCP上でプロジェクトを作成する必要があります。

プロジェクトとは、ここでは1つの「作業場」と捉えていただければ問題ありません。

では、プロジェクトを早速作っていきます。

アカウント作成後に、GCPのトップページへ行くと、以下の通りページのヘッダーが表示されます。

GCP top page

“Google Cloud Platform”タイトルの右横のドロップダウンをクリックし、以下の画面で「New Project」ボタンを押します。

Create project

Locationは特に設定する必要はないので、そのまま”Create”ボタンを押します。

Create project 2nd

これで、プロジェクトが作成されました。

project is created

サービスアカウントの作成

続いて、作成されたプロジェクトの中に、サービスアカウントを作成します。

先ほど作ったプロジェクトは「作業場」と捉えておけば問題ない、という話をしました。

その「作業場」の中に、今度はサービスアカウント作ります。

サービスアカウントは、要は「仮想的な1ユーザー」と捉えていただければ問題ないと思います。

この仮想的なユーザーを作り、後ほど、このユーザーにGoogle Analyticsへのアクセス許可を与えてあげる、という事をします。

では、サービスアカウント(仮想的なユーザー)を作っていきます。

GCPのトップページから、先ほどと同じように”Google Cloud Platform”タイトルの右横のドロップダウンリストより、作成されたプロジェクトを選択します。

select created project

トップページのハンバーガーアイコンから、IAM&Admin -> Service accountsを選択します。

Choose service accounts

そして、“CREATE SERVICE ACCOUNT”ボタンを押します。

create service account

Service account nameに名前をつけ、“CREATE”ボタンを押します。 create service account 2

Roleは選ぶ必要はないので、そのまま”CONTINUE”を押します。

skip role seeting

そして、“Done”ボタンを押しましょう。

finished service account creation

これで、サービスアカウントの作成が完了しました。

ハンバーガーメニューからIAM & Admin -> Service Accountsをクリックすると、作成されたサービスアカウントを確認できます。

ここで表示されているEmailアドレスが大事なので、これをメモリましょう。

check service accounts

作ったサービスアカウントをクリックすると以下のように詳細が表示されます。

ここで、keyを取得する必要があるので、ADD KEY -> Create new keyを選択しましょう。

create new key

JSON形式でダウンロードします。

download json key

これで、keyを取得できました。

download is completed

サービスアカウント(仮想的なユーザー)の作成で、KeyとEmailアドレスを得ることができましたので、次のステップでそれらを使っていきます。

Google Analyticsへのアクセス権限をサービスアカウントに付与する

続いて、作ったサービスアカウントに対して、Google Analyticsへのアクセス権限を付与します。

Google Analyticsへサービスアカウントを登録

先ずは、Google Analyticsへサービスアカウントを登録します。

Google Analyticsの管理画面から、Property User Managementを選択します。

Property user management

右上の+ボタンからAdd Userを選択します。 Add user

先ほどメモしたEmailアドレスを入力し、右上のAddボタンを押します。 Permissionsはデフォルトのままで問題ありません。

Add user 2

Google Analytics APIを導入する

続いて、Google Analytics APIをGCPに導入します。

GCP管理画面から、APIs & Services -> Libraryを選択します。

introduce google analytics api to gcp

Google Analytics APIを選択し、Enableボタンを押します。

select google analytics API

これで、Google Analyticsへのアクセス権限をサービスアカウント(仮想的なユーザー)に付与できました。

これ以降はGatsby側での設定です。

GatsbyでGoogle Analyticsのデータを引っ張ってくる

先ずは、google analytics reporting APIのpluginをインストールします。

Terminal
npm install gatsby-source-google-analytics-reporting-api --save

そして、gatsby-config.jsファイルにて、プラグインの設定をします。

gatsby-config.js
{
      resolve: `gatsby-source-google-analytics-reporting-api`,
      options: {
        email: process.env.CLIENT_EMAIL,
        key: process.env.PRIVATE_KEY.replace(/\\n/g, "\n"),
        viewId: `xxxxxx`,
        startDate: `2020-06-16`,
      },
    },

CLIENT_EMAILPRIVATE_KEYは、開発環境と本番環境で設定方法が違うので、後ほど解説します。

viewIDはGogole AnalyticsのAdmin > View Settingsから確認できます。

view settings

では、CLIENT_EMAILPRIVATE_KEYの設定です。

先ずは開発環境から見ていきましょう。

開発環境でGoogle Analyticsデータを読み込む

gatsbyブログのルート直下に.env.developmentファイルを作成し、サービスアカウントのEmailアドレスとKeyを格納します。

.env.development
CLIENT_EMAIL=xxxx@xxxx.iam.gserviceaccount.com
PRIVATE_KEY=-----BEGIN PRIVATE KEY-----xxxxx-----END PRIVATE KEY-----

ここで、PRIVATE_KEYは、フォーマットが正しくないと動作しないため注意が必要です。

以下で、正しいPRIVATE_KEYの取得方法を解説します。

まず、先ほどダウンロードしたjsonファイルから、private_keyの値をコピーします。

この時、両端の"は必要ないので、-----BEGIN PRIVATE KEY-----から、\n-----END PRIVATE KEY-----\nまでで結構です。

そして、新しくエディターを開き、コピーしたデータを貼り付けます。

copy json private key

VS Codeであれば、Toggle Word Wrapをクリックします。

toggle word wrap

すると、以下のようにコードが表示されます。

toggled

そして、/nを削除したいので、ブランクで置換します。

replace /n

最後に、もう一度View -> Toggle Word Wrapボタンを押し、一行で表示するようにします。

three lines of code

これを、.env.developmentファイルに格納しましょう。

.env.development
CLIENT_EMAIL=xxxx@xxxx.iam.gserviceaccount.com
PRIVATE_KEY=-----BEGIN PRIVATE KEY-----xxxxx-----END PRIVATE KEY-----

.env.*はgitignoreしておきます。

.gitignore
...
.env*

そして、gatsby-config.jsファイルにて、開発環境時に.eng.*が読み込まれる設定を行います。

gatsby-config.js
const activeEnv =
  process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || 'development';
require('dotenv').config({
  path: `.env.${activeEnv}`,
});

module.exports = {
  siteMetadata: {
    ...

これで、開発環境でGoogle Analyticsデータを読み込めるようになりました。

そのまま開発環境で人気記事一覧の実装へ進みたい方は、本番環境の設定を飛ばしてください。

人気記事一覧をサイドバーへ載せる

本番環境でGoogle Analyticsデータを読み込む

では、本番環境(Netlify)でGoogle Analyticsデータを読み込む設定を行います。

NetlifyのBuild & Deploy -> Environment variablesから、CLIENT_EMAILPRIVATE_KEYの値を設定します。

先ほど、.env.developmentで設定した値をそのまま使ってください。

Setting on Netlify

これで、本番環境でGoogle Analyticsデータを引っ張ってくる準備ができました。

人気記事一覧をサイドバーへ載せる

さて、最後です。

Google Analyticsから取得したデータをGatsbyブログで表示させます。

Componentsフォルダー直下に、PopularPagesというフォルダーを作ります。

Google AnalyticsのデータはGraphQLのallPageViewsに入っているので、そのデータを取り出し、そして記事データも併せて取り出します。

記事idをアクセス数の多い順に並べ替え、top pageは除外し、そして、top10の人気記事に絞りこんで一覧を表示させております。

/src/components/PopularPages/index.jsx
import React from 'react'
import { useStaticQuery, Link, graphql } from 'gatsby'
import './style.scss'

export default function PopularList() {

    const data = useStaticQuery(graphql`
      query allPageViews {
        allPageViews {
          edges {
            node {
              totalCount
              id
            }
          }
        }
        allMarkdownRemark(
          sort: { fields: [frontmatter___date], order: DESC }
          limit: 2000
        ) {
          edges {
            node {
              fields {
                slug
              }
              frontmatter {
                title
              }
            }
          }
        }
      }
    `);

    const posts = data.allMarkdownRemark.edges;

    const allPosts = data.allMarkdownRemark.edges;
    const appPageViews = data.allPageViews;
    const results = [];

    const modifiedAppPageViews = appPageViews.edges
    .sort(({ node: a }, { node: b }) => b.totalCount - a.totalCount) // countの大きい順にソートしている。
    .filter(({ node }) => node.id !== '/') // TOPページは除外する
    .slice(0, 10) // top 10の人気記事のみ抽出
    .forEach(({ node }) => {
      posts.forEach(({ node: post }) => {
        if (post.fields.slug === node.id) {
          results.push({
            count: node.totalCount,
            ...post,
          });
        }
      });
    });

   return (
      <div>
      <h1 className="popularlist-header">人気記事</h1>
      <table className="popular-list">       
        {results.map((result, i) => (
          <tbody key={result.frontmatter.title}>
            <tr key={result.frontmatter.title} className="popular-list-item">
              <td><span><b>{i+1}</b></span></td>  
              <td className="popular-list-item-box">
                <Link className="popular-list-item-box-link" to={result.fields.slug}>
                  <span style={{display: 'inline'}}>{result.frontmatter.title} {/* {result.count} */}</span>
                </Link>
              </td>
            </tr>
          </tbody>
        ))}
      </table>
      </div>
    )
};

PopularPagesのcomponentができたら、最後にSidebarへ埋め込み、scssでコスメティクスを整えましょう。

/src/components/Sidebar/index.jsx
...
import PopularList from '../PopularPages'
...
return (
  <div className="sidebar">
    <div className="sidebar__inner">
      <AdsenseSidebar />
      {/* <div className="sidebar__author">{authorBlock}</div> */}
      <div>
        {/* following is google search box */}
        <ClientOnly>
          <Search />
        </ClientOnly>
        <PopularList />
        ...

まとめ

この記事では、Gatsbyブログに人気記事一覧を実装する方法を解説しました。次は最新記事一覧をサイドバーに追加しましょう。

シェアする