December 29, 2020

GatsbyJS + Wordpressで高速ブログを構築する

WordPressをコンテンツ管理システムとしてのみ使用し、GatsbyJSで投稿データを取得して、静的サイトを生成する方法を紹介します。WordpressをヘッドレスCMSとして使うことで、よりページの高速化をはかれます。

Updated at December 24, 2020

WordPressをコンテンツ管理システムとしてのみ使用し、GatsbyJSで投稿データを取得して、静的サイトを生成する方法を紹介します。

WordpressをヘッドレスCMSとして使うことで、よりページの高速化をはかれます。


Wordpress側の準備

Wordpressをインストール

まずは、Wordpressで作られたサイトを用意します。

既にお持ちの方はそれを使ってもいいですし、無い方は新たにインストールして用意してください。

私は今回、Local を使って、WordPressのローカル環境をさくっと構築しました。

プラグインをインストール

Wordpressのアドミンから、下記2つのプラグインをインストールし、有効化しておきます。

wordpress-plugins

これで、WordpressのデータをGraphQLで取得する準備が出来ました。


新しいGatsbyプロジェクトを作成

前提条件

Gatsbyは、NodeJSのパッケージインストーラーであるnpmを介して配信されるので、あなたの環境にNodeJSとnpmがインストールされていることが前提です。

NodeJS

ターミナル
node -v
v12.19.0

npm

ターミナル
npm -v
6.14.10

Gatsby

もし、まだGatsbyをインストールしてない場合は、下記のコマンドでインストールしましょう。

ターミナル
npm install -g gatsby-cli

Gatsbyサイトを作成

gatsby new コマンドを実行して、/gatsby-wordpress/ ディレクトリにGatsbyスターターテンプレートをクローンして、新しいプロジェクトを作成します。

今回、プロジェクトの名前は gatsby-wordpress にしました。

ターミナル
gatsby new gatsby-wordpress

Gatsbyサイトをデプロイ

先ほど作成したプロジェクトへ移動し、

ターミナル
cd gatsby-wordpress

とりあえず、何も触らずに gatsby develop コマンドを実行してデプロイしてみます。

ターミナル
gatsby develop

開発サーバ http://localhost:8000 にアクセスすると、

default-starter

おなじみ、Gatsbyのスターターおじさんが表示されました👍


GatsbyとWordPressの統合

では、Gatsbyのビルド時に、WordPressに投稿してあるブログ記事データを取得し、テンプレートに基づいて静的ファイルを生成するようにして行きましょう。

パッケージをインストール

まずは、必要なパッケージをインストールします。

GatsbyでWordpressデータを取得するプラグインと言えば、gatsby-source-wordpressなんですが、

Warning: The current version of this plugin will soon be deprecated and replaced with a complete rewrite in the next version (v4).

Please upgrade to the beta of gatsby-source-wordpress@v4 by installing gatsby-source-wordpress-experimental.

と、まぁ、このプラグインの現バージョン(v3)はまもなく非推奨となるので、gatsby-source-wordpress-experimentalをインストールしてください、とのことなので、言われた通りに。

ターミナル
npm install gatsby-source-wordpress-experimental

参考:

gatsby-configに定義

インストールしたプラグインを、Gatsbyの構成ファイルである gatsby-config.js に追加します。

gatsby-config.js
module.exports = {
  siteMetadata: {
    ...
  },
  plugins: [
    ...
    {
      resolve: `gatsby-source-wordpress-experimental`,
      options: {
        url: `http://gatsby-wordpress.local/graphql`,
      },
    },

url には、あなたのWordpressサイトのURLを入力してくださいね。


GraphQLで投稿データを取得する

ここまで出来たら、gatsby develop を実行し、Wordpressの記事を取得出来ているか、ブラウザからGraphQLエディター http://localhost:8000/___graphql にアクセスして確認しましょう。

graphql-wordpress

問題なく投稿データを取得出来ていますね😊


トップページにブログ記事一覧を表示

まずは、トップページにブログ記事一覧を表示します。

今回は、各投稿から、

  • 投稿日(date)
  • スラッグ(slug)
  • タイトル(title)
  • アイキャッチ画像(featuredImage)

の4つを引き出して使用します。

index.js ファイルを下記のように変更します。

/src/pages/index.js
import React from "react"
import { Link, graphql } from "gatsby"
import Img from "gatsby-image"

import Layout from "../components/layout"
import SEO from "../components/seo"

const IndexPage = ({ data }) => {
  const posts = data.allWpPost.edges
  return (
    <Layout>
      <SEO title="Home" />
      {posts.map(({ node }) => (
        <div key={node.slug}>
          <div>{node.date}</div>
          <h3>
            <Link to={node.slug}>{node.title}</Link>
          </h3>
          <Img
            fixed={node.featuredImage.node.localFile.childImageSharp.fixed}
            alt={node.title}
          />
        </div>
      ))}
    </Layout>
  )
}

export default IndexPage

export const pageQuery = graphql`
  query HomeQuery {
    allWpPost(sort: { fields: [date], order: DESC }) {
      edges {
        node {
          date(formatString: "YYYY/MM/DD")
          slug
          title
          featuredImage {
            node {
              localFile {
                childImageSharp {
                  fixed(width: 500, height: 500) {
                    ...GatsbyImageSharpFixed
                  }
                }
              }
            }
          }
        }
      }
    }
  }
`

開発サーバ http://localhost:8000 にアクセスすると、

gatsby-wordpress-index

トップページにHello World!の記事が表示されていますね!


各ブログ記事ページを作成する

createPageで各ブログ記事ページを生成

gatsby-node.js ファイルに、createPage アクションを追加して、各ブログ記事ページを生成します。

gatsby-node.js
const path = require(`path`)

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  return graphql(`
    {
      allWpPost {
        nodes {
          slug
        }
      }
    }
  `).then((result) => {
    result.data.allWpPost.nodes.forEach((node) => {
      createPage({
        path: node.slug,
        component: path.resolve(`./src/templates/blog-post.js`),
        context: {
          // This is the $slug variable
          // passed to blog-post.js
          slug: node.slug,
        },
      })
    })
  })
}

ここでポイントは、

  • 生成する各ブログ記事ページのURL構造は path に指定。今回は各記事のスラッグ名にしているので http://localhost:8000/your-slug/
  • blog-post.js をテンプレートにして、ページを生成する
  • context に slug の値を渡す

ブログ記事ページ用のテンプレートを作成

新たに /src/templates/blog-post.js ファイルを作成します。

ブログ記事ページには、

  • 投稿日(date)
  • スラッグ(slug)
  • タイトル(title)
  • アイキャッチ画像(featuredImage)
  • コンテンツ(content)

を引き出して表示します。

/src/templates/blog-post.js
import React from "react"
import Layout from "../components/layout"
import { graphql } from "gatsby"
import Img from "gatsby-image"

export default function BlogPost({ data }) {
  const post = data.allWpPost.nodes[0]
  console.log(post)
  return (
    <Layout>
      <div>{post.date}</div>
      <h1>{post.title}</h1>
      <Img
        fluid={post.featuredImage.node.localFile.childImageSharp.fluid}
        alt={post.title}
      />
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </Layout>
  )
}
export const pageQuery = graphql`
  query WpPostBySlug($slug: String!) {
    allWpPost(filter: { slug: { eq: $slug } }) {
      nodes {
        date(formatString: "YYYY/MM/DD")
        slug
        title
        featuredImage {
          node {
            localFile {
              childImageSharp {
                fluid(maxWidth: 1200) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        }
        content
      }
    }
  }
`

先ほど context に渡した値、$slug を使って、記事データを取得する時にフィルターをかけています。

この部分ですね。

query WpPostBySlug($slug: String!) {
  allWpPost(filter: { slug: { eq: $slug } }) {
  ...

ここまで出来たら、gatsby deploy してみましょう。

gatsby-wordpress-blog-post

blog-post.js によってレンダリングされたブログ記事ページが表示されてますね🙌


想像以上にサクッと出来ました😊

今回はミニマムな情報のみを取得して表示してみましたが、Wordpressのその他の機能、ページ、カテゴリー、タグ、カスタム投稿タイプ、タクソノミー、カスタムフィールドなども追加してみたいと思います。

高橋あゆみ

高橋あゆみ
フリーランスのUI/UXデザイナー。英語圏のロマンス・ミステリー小説にハマり、一向に減らない積読が悩み。カナダのバンクーバー在住。