Wiz テックブログ

Wizは、最新のIoTやICTサービスをお客様に届ける「ITの総合商社」です。

GatsbyJsでWordPressをHeadless CMSとしてサイト構築deployまで試してみました。

f:id:thunder_fury:20210226181958p:plain

はじめに

皆さんこんにちは、フロントエンドエンジニアのWooです。
GatsbyJsでWordPressをHeadless CMSとして使用した構築方法や個人的に考えたメリットやデメリットをお話ししたいと思います。

WordPressのメリットとしてはサイト構築が楽でプラグインインストールで実装も簡単にできる便利なツールですが、サイトが多少重くてセキュリティ面でも不正な操作や攻撃を受けやすいのでバージョン管理やプラグインのバージョン管理などが大変です。

GatsbyJsで構築をするとWordPressのバージョン管理は行わなくて良くて、サイトもSSG(Static Site Generator)仕様なので非常に早いサイトを構築することができます。

WordPressが構築されている前提で、進めていきたいと思います。

GatsbyJsとは何か

GatsbyJsはReactベースの静的サイトジェネレーターです。
WordPressは、記事の「閲覧時」に動的にサイト内容が生成されますが、GatsbyJsは「ビルド時」にHTMLやCSSなどがあらかじめ生成されていることが特徴で、WordPressと比べてビルド時にhtmlを用意しているのでサイトが非常に早くなるメリットがあります。つまり、SSG(Static Site Generator) 仕様ということです。

GatsbyJs公式サイトは速度だけではなくサイトのセキュリティ補完もできると書かれています。 www.gatsbyjs.com

Security by default
Gatsby’s serverless rendering generates static HTML at build time. No server and no reachable database equals no malicious requests, DDOS attacks, or accidental exposure. A Gatsby site’s attack surface is nonexistent.

上記の内容を翻訳した内容です。

デフォルトのセキュリティ
Gatsbyのサーバーレスレンダリングは、ビルド時に静的HTMLを生成します。サーバーや到達可能なデータベースがないことは、悪意のある要求、DDOS攻撃、または偶発的な露出がないことを意味します。Gatsbyサイトの攻撃対象領域は存在しません。

WordPressのセキュリティの改善もできそうです。

GatsbyJs導入install

$ npx gatsby-cli gatsby new [project名]

ローカルサーバー起動

$ cd project名
$ gatsby develop

無事ローカルサーバーが起動できました。 f:id:thunder_fury:20210226123304p:plain

ローカルサーバーが立ち上がったところでページのレンダリングを確認をしてみると、GatsbyJsはマウスホバーをする時点でプリフェッチ (prefetch)と呼ばれる処理が走り、ページのdataが先に通信されるので早いなあと思いました。🤔

f:id:thunder_fury:20210226133314g:plain

WordPressと連動

GatsbyJsにはいろんなプラグインが存在していてWordPressと繋ぐのはgatsby-source-wordpressが一番簡単だったので自分はgatsby-source-wordpressをインストールしました。

$ npm i gatsby-source-wordpress

インストールが終わりましたらgatsby-config.jsに設定する必要があります。

module.exports = {
plugins: [
 ...省略...
  {
      resolve: `gatsby-source-wordpress`,
      options: {
        baseUrl: `〇〇〇〇.com`, // ワードプレスURL
        protocol: `https`,
        hostingWPCOM: false,
        useACF: true,
        // fetchしたいcontent
        includedRoutes: [
          "**/posts",
          "**/media",
        ],
      },
    },
 ...省略...
 ]
}

今回はpostsとmediaだけフェッチを行い、titleとアイキャッチの画像を取得したいと思います。 他にも習得できるkeyは存在しております。

  • "**/categories" カテゴリー
  • "**/pages" 固定ページ
  • "**/tags" タグ
  • "**/users" ユーザー情報(記事を書いた人の情報など)

GraphiQLからシミュレーションをしてみたらWordPressの最初の記事Hello Worldが取得されているのが分かります。

f:id:thunder_fury:20210227144451p:plain

GatsbyJs側の処理

config設定

const Promise = require("bluebird")
const { resolve } = require("path")
const path = require(`path`)

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  return new Promise((resolve, reject) => {
    const wpPosts = path.resolve("./src/templates/blog-post.js")
    resolve(
      graphql(`
        {
          allWordpressPost(sort: { fields: [date] }) {
            edges {
              node {
                slug
              }
            }
          }
        }
      `).then(result => {
        if (result.errors) {
          reject(result.errors)
        }
       const posts = result.data.allWordpressPost.edges
       // { node }で記載のgraphqlデータを習得することができます。
        posts.forEach(({ node }) => {
          createPage({
            path: node.slug,
            component: path.resolve(`./src/templates/blog-post.js`),
            context: {
              slug: node.slug,
            },
          })
        })
      })
    )
  })
}

記事一覧ページ

記事リストを展開表示する処理は下記です。 自分はtopに表示したかったのでpages/index.jsに記載をしました。 もし、別ページにしたい場合はディレクトリーのpagesの中にファイルを追加して別ページに記載することも可能です。

import React from "react"
import { Link, graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"

export const Index = ({
  data
})  => {
  const posts = data.allWordpressPost.edges
  return (
    <Layout>
      <SEO title="home" />
      <h1>My WordPress Blog</h1>
      <h4>Posts</h4>
      <ul>
        {posts.map((post, index) => {
          return (
            <li key={post.node.slug}>
              <img src={post.node.featured_media.source_url} alt="thunder fury"/>
              <Link to={post.node.slug}>{post.node.title}</Link>
            </li>
         )})}
      </ul>
    </Layout>
  )
}

export const pageQuery = graphql`
  query {
    allWordpressPost {
      edges {
        node {
          title
          slug
          featured_media {
            source_url
            title
          }
        }
      }
    }
  }
`
export default Index

f:id:thunder_fury:20210301121433p:plain

記事テンプレート作成

import React from "react"
import Layout from "../components/layout"
import { graphql } from "gatsby"
import styled from "styled-components"

export default ({ data }) => {
  const post = data.allWordpressPost.edges[0].node
  return (
    <Layout>
      <div>
        <h1>{post.title}</h1>
        <Img src={post.featured_media.source_url} alt="thunder fury" />
      </div>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </Layout>
  )
}
export const query = graphql`
  query($slug: String!) {
    allWordpressPost(filter: { slug: { eq: $slug } }) { 
      edges {
        node {
          title
          slug
          content
          featured_media {
            source_url
            title
          }
        }
      }
    }
  }
`

記事ページも問題なく表示されました。

f:id:thunder_fury:20210227145735p:plain

NetlifyでDeploy

f:id:thunder_fury:20210301131500p:plain

Netlifyとは何か

Netlifyは静的なページを無料で作成し、Deployすることができるホスティングサービスです。

特徴としてはHTTPSを提供し、GitHubの特定Repoの特定のブランチがPushされるたびに自動的にビルドのデプロイを行ってくれるという点です。

無料枠としては1チームまで毎月300回Deployができて同時ビルドは一人しかできませんが個人であれば十分使えると思いました。

デプロイ手順

  1. Netlifyに加入する。
  2. GitHub、GitLab、Bitbucketの中から接続するサービスを選択。
  3. 選択したサービスの特定のRepoを選択。
  4. 選択したRepoのBranchを選択。
  5. ビルドスクリプト(例gatsby build)を入力。
  6. 作成されたフォルダ(例/public)を入力。
  7. ビルドとデプロイの実行を見守る。

参考イメージ

f:id:thunder_fury:20210301124130p:plain

f:id:thunder_fury:20210301124647p:plain

f:id:thunder_fury:20210301124627p:plain

3ステップで簡単にDeployができます。

まとめ

WordPressをHeadless CMSとして使えるか試しに環境構築をしてみました。

GatsbyJsはWordPressと簡単に繋げることができ、WordPressのデメリットをGatsbyJsが補完してくれるため、編集者はいつも通りWordPressで管理が出来るようになります。

フロントエンドエンジニアはビューの開発に集中できる印象を受けました。

記事の検索や関連記事表示のサイトの機能は全部自分で用意をしないといけませんが、サイトのパフォーマンスがよくなるので一度チャレンジしてもありかと思いました。


最後になりますが、Wizではエンジニアを募集中です!

色んな案件の経験ができるので興味のある方は是非覗いてみてください↓

【フロントエンドエンジニア】
場所にとらわれず自社メディア成長に貢献したいフロントエンドエンジニア募集! - 株式会社WizのWebエンジニアの求人 - Wantedly

【バックエンドエンジニア】
勤務地自宅を叶える!バックエンドエンジニアとして事業を成長させたい方募集 - 株式会社WizのWebエンジニアの求人 - Wantedly