WordPressベースの動的ウェブサイトは次のように機能します。訪問者がブラウザーでURLを入力するか、リンクをクリックしてサイトにアクセスすると、ウェブサーバーにリクエストが送信されます。

サーバーは、該当のデータベースクエリで必要なデータを収集し、ブラウザが表示するHTMLファイルを生成します。一方、静的サイトは、上記の応答をサーバー上のフラットファイルに保存し、すぐに訪問者に配信します。

静的サイトジェネレーターは長い間使用されてきましたが、最近人気が高まっています。本ステップバイステップガイドでは、WordPressと静的サイトジェネレーターであるGatsbyの統合について説明します。

Gatsbyとは?

WordPressは動的なウェブサイトを作成しますが、実行するにはサーバー上にPHPMySQLApacheまたはNginxのスタックが必要です。サイト上のすべてのコンテンツのHTMLページのリストを生成することにより、WordPressの静的バージョンを作成することは可能です。

WordPressのこの静的バージョンは、ヘッドレスWordPressまたはサーバーレスWordPressと呼ばれます。同じページは何回も訪問者に配信可能ですが、変換プロセスは一度だけ実行されます。 さて、どうやってWordPressサイトを静的バージョンに変換すれば良いのでしょうか?そこで、Gatsbyが登場します。

Gatsby(GatsbyJSとも)は、ReactJSで構築され、GraphQLを活用した静的サイトジェネレーターです。Gatsbyでは、誰でも機能豊富で魅力的なウェブサイトやアプリケーションを作成できます。Gatsbyは、GraphQLを使用して既存のウェブサイト、API呼び出しやフラットファイルなどのさまざまなソースからサイトのデータを取得し、指定した設定に基づいて静的サイトを構築します。

Gatsbyは1年前に開発されましたが、それ以降多くのユーザーがGatsbyを試用していきました。Gatsbyは広く好まれています。たとえば、AirbnbのデータサイエンスおよびエンジニアリングブログのホームページもGatsbyを使用しています。(一方、のブログ投稿はMediumでホストされています。)

Airbnbのデータサイエンスおよびエンジニアリングブログ
Airbnbのデータサイエンスおよびエンジニアリングブログ

Braunは、消費財企業P&Gのブランドです。カナダのサイトはGatsbyでホストされていますが、サイトの検索機能はReactを基盤としています。

Braunのカナダのウェブサイト
Braunのカナダのウェブサイト

さらに、Gatsbyはポートフォリオを作成したいフリーランサーの開発者の関心も刺激しています。たとえば、Jacob Castroのようなポートフォリオには、作品へのリンクや電子メールの連絡先以外には静的コンテンツしかないため、静的サイトは彼のニーズに最適です。

Jacob D. Castroのポートフォリオ
Jacob D. Castroのポートフォリオ

Gatsbyを選ぶ理由

高速なウェブサイト:Gatsbyの静的サイトを構築する主な利点は、Googleがウェブ検索ランキングでサイトの速度を使用することを発表して以来、ウェブマスターは最適化しようとしているスピードです。読み込み時間はページビュー数とコンバージョン率にも影響します。サイトの読み込み時間が1秒遅れると、コンバージョン率が7%減少すると推定されています。

セキュリティ:静的サイトを使用すると、セキュリティ も強化されます。静的ファイルしか配信されないため、ハッキングできろものはほとんどありません。さらに、静的ファイルが失われた場合は、いつでも再生成できます。

サーバーコスト:動的サイトをホストするには、サーバーがテクノロジスタックと互換性がある必要があります。静的サイトなら、どのサーバーでもホストでき、ホスティング費用が減少します。

Gatsbyを使用して静的サイトを生成するには、各変更の際にJavaScriptが必要ですが、JavaScriptは静的ファイルをサイトに転送する前にローカルマシンで実行することもできます。

Gatsbyを選ばない理由

ダイナミックコンテンツの組み込みがない:Gatsbyを使用すると、ダイナミックコンテンツの管理方法と配信方法を再考する必要があります。つまり、静的と動的のハイブリッドを作成しなければなりません。(詳細については以下説明します。)

たとえば、コメントは、Disqusなどのサービスを使用して外部でホストする必要があります。

お問い合わせフォームも、Google Formsなどの外部パートナーを使用して再設定する必要があります。要するに、動的コンテンツに対する応答はサーバーに保存されないため、直接に管理できなくなります。

頻繁な構築は不便: 静的サイトには、頻繁な再変換の問題もあります。サイトで行った変更は、ページを再生成してサーバーに再アップロードした後にしか反映されません。

技術的専門知識: GatsbyはReactJSとGraphQLを基盤としています。したがって、ウェブサイトをGatsbyで作成して管理するには、JavaScriptとGraphQLの基本的な知識が必要です。

静的ウェブサイトは、高セキュリティで低コストのソリューションを探している人に適しています。たとえば、フリーランサーのポートフォリオサイトや製品デモサイトなどはよくあるユースケースです。

メリットがデメリットを上回ると判断した方は是非試してみてください。次に、GatsbyをWordPressサイトと統合するように設定しましょう。

本チュートリアルで作成するGatsbyサイトの最新バージョンは、GitHubで利用可能になっています。

ステップ1:Gatsbyの設定

このセクションでは、Gatsbyをインストールして簡単な静的サイトを作成する方法について説明します。

前提条件

Gatsbyを使い始めるための最初のステップは、前提条件を確認することです。Gatsbyは、NodeJSパッケージインストーラーであるnpmを介して配信されます。 したがって、Gatsbyをインストールする前に、環境にNodeJSとnpmが必要です。さらに、Gatsbyでは、ソースコード管理システムであるGitをインストールする必要があります。

Windowsをご利用の場合、ダウンロードページのインストーラーでNodeJSとGitをインストールできます。Macでは、インストーラーをダウンロードするか、homebrewを使用します。

brew install nodejs
brew install git

Linux OSをご利用の場合、aptなどのパッケージインストーラーを使用してNodeJSをインストールできます。

sudo apt update
sudo apt install nodejs git

Gatsbyのインストール

NodeJSとGitを正常にインストールしてから、Gatsbyをインストールする準備ができました!最も簡単な方法は、ターミナルで次のコマンドを実行することです。(Windowsではnpmコマンドラインを使用します。)

npm install -g gatsby-cli

インストーラーは最初に依存関係をインストールし、次にGatsbyをインストールします。これで、Gatsbyサイトを作成する準備ができました。

Gatsbyサイトを構築してデプロイする

次のコマンドを実行して、Gatsbyサイトを作成します。

gatsby new gatsby-wordpress

Gatsbyは、Gatsbyスターターテンプレートのクローン作成により、/gatsby-wordpressディレクトリにサイトを作成します。 ご希望の別のスターターテンプレートを提供することも可能です。クローン作成が完了し、依存関係がインストールされてから、次のコマンドでサイトの開発版を実行できます。

cd gatsby-wordpress
gatsby develop

その後、http://localhost:8000でサイトの開発版にアクセスできます。

Gatsbyスターターサイト
Gatsbyスターターサイト

最後のステップは、静的サイトを構築することです。次のコマンドは、パブリックディレクトリに静的ファイルを作成します。サーバーにアップロードするには、このディレクトリのコンテンツをサーバーのルートディレクトリにアップロードするだけです。ルートURLとしてwww.example.com/blog/などパスプレフィックスを追加することもできます。

gatsby build

静的サイトを表示するHTMLサーバーをローカルで起動するにはserveコマンドを使用します。なお、これはbuildコマンドを実行した後でないと機能しないことにご注意ください。

gatsby serve

これでGatsbyで簡単な静的サイトを作成できました。次に、WordPressと統合してみましょう。

ステップ2:GatsbyとWordPressの統合

このセクションでは、WordPressサイトをGatsbyと統合します。開発サーバーを実行するとき、または静的ページを生成するときに、GatsbyがWordPressブログのアドレスに指し、最新のデータを引き出せるようにします。

GatsbyをWordPressに接続するプロセスは、ビルドによってトリガーされるWordPressデータをフェッチすることです。GatsbyはWordPressデータを取得すると、現在のテンプレートに基づいて静的サイトを作成します。

WordPressサイトを使用するプロセスには、Gatsbyでも投稿のソースがあります。この交換を容易にするには、次のコマンドを使用して、GatsbyのWordPressプラグインをインストールする必要があります。

npm install gatsby-source-wordpress

Gatsbyの構成

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

次に、次のコードをファイルに追加して、GatsbyをWordPressソースに接続します。この例では、MAMPでローカルにホストされているWordPressサイトを使用します。補足ですが、siteMetadataでサイトのタイトルと説明を編集することもできます。

module.exports = {
  siteMetadata: {
    ...
  },
  plugins: [
    ...
    {
        resolve: `gatsby-source-wordpress`,
        options: {
            // Specify the URL of the WordPress source
            baseUrl: `localhost:8888/wordpress`,
            protocol: `http`,
            // Indicates if a site is hosted on WordPress.com
            hostingWPCOM: false,
            // Specify which URL structures to fetch
            includedRoutes: [
              '**/posts',
              '**/tags',
              '**/categories'
            ]
        }
    }

GraphQLで投稿をフェッチする

構成ファイルでWordPressサイトのソースを指定してから、WordPressサイトから抽出するデータを指定します。 Gatsbyは、APIのオープンソースクエリ言語であるGraphQLを使用して、WordPressの投稿をまとめて取得します。

指定するクエリを確定する前に、WordPressから取得する必要のあるコンテンツをインタラクティブに選択できます。開発サーバーを実行し、「http://localhost:8000/___graphql」にアクセスして、GraphQLエディターを開きます。

GraphQLで見たデータのクエリ
GraphQLで見たデータのクエリ

引き出すコンテンツを指定してから、GraphQLクエリをindex.jsファイルに追加できます。

今回は、各投稿からタイトルと抜粋のみを引き出しましょう。後でフィールドを増やしてもかまいません。

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

export default ({ data }) => {
  return (
    <Layout>
      <SEO title="home" />
      <h4>Posts</h4>
      {data.allWordpressPost.edges.map(({ node }) => (
        <div>
          <p>{node.title}</p>
          <div dangerouslySetInnerHTML={{ __html: node.excerpt }} />
        </div>
      ))}
    </Layout>
  )
}
export const pageQuery = graphql`
  query {
    allWordpressPost(sort: { fields: [date] }) {
      edges {
        node {
          title
          excerpt
        }
      }
    }
  }

開発サイトを確認すると、各WordPress投稿の見出しと抜粋が引き出されていることがわかります。

WordPressの投稿があるGatsbyホームページ
WordPressの投稿があるGatsbyホームページ

見た目はあまりきれいではありませんが、WordPressから関連データを正常に引き出すことができました。次のステップは、投稿ごとに新しいページを作成することです。

ステップ3:簡単なページテンプレートを作成する

このセクションでは、WordPressサイトのすべてのページに対して投稿を作成してスラッグを使用して投稿へのリンクを含めるするようにGatsbyをトリガーします。

各投稿のページを作成する

WordPressソースからすべての投稿を引き出した後の最初のステップは、各投稿のページを作成するようにGatsbyに指示することです。これを行うには、createPageアクションを使用します。

次のコードをgatsby-node.jsに追加します。各投稿のコンテンツ、作成者、日付、スラッグを追加で取得していることにご注意ください。

const path = require(`path`)

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  return graphql(`
    {
      allWordpressPost(sort: {fields: [date]}) {
        edges {
          node {
            title
            excerpt
            slug
            date(formatString: "MM-DD-YYYY")
            author {
              name
            }
          }
        }
      }
    }

  `).then(result => {
    result.data.allWordpressPost.edges.forEach(({ node }) => {
      createPage({
        // Decide URL structure
        path: node.slug,
        // path to template
        component: path.resolve(`./src/templates/blog-post.js`),
        context: {
          // This is the $slug variable
          // passed to blog-post.js
          slug: node.slug,
        },
      })
    })
  })

GraphQLからデータを取得した後、コードは各投稿のページを作成します。投稿内で、パスを使用してスラッグに基づいてページのURL構造を指定できます。

または、投稿のIDを取得して、URLで指定することもできます。コンポーネント変数は、投稿をレンダリングするテンプレートを指します。最後に、テンプレートのコンテキストとしてスラッグを使用します。これは、テンプレートがフェッチされた投稿一覧から正しい投稿をクエリするために必要です。

理想的には、投稿をコンテキストとして指定する変数を渡す必要があります。

gatsby-node.jsファイルに変更を加えた後、変更を有効にするに開発サーバーを再起動します。

投稿を表示するテンプレートを作成する

srcディレクトリにディレクトリテンプレートを作成します。テンプレートディレクトリ内に新しいファイルblog-post.jsを作成し、次のコードを入力します。

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

export default ({ data }) => {
  const post = data.allWordpressPost.edges[0].node
  console.log(post)
  return (
    <Layout>
      <div>
        <h1>{post.title}</h1>
        <div dangerouslySetInnerHTML={{ __html: post.content }} />
        <p> By: {post.author.name} </p>
        <p> On: {post.date} </p>
      </div>
    </Layout>
  )
}

export const query = graphql`
  query($slug: String!) {
    allWordpressPost(filter: { slug: { eq: $slug } }) {
      edges {
        node {
          title
          content
          slug
          date(formatString: "MM-DD-YYYY")
          author {
            name
          }
        }
      }
    }
  }

GraphQLクエリは投稿の最後に表示される日付と作成者名を取得します。GraphQLエディターを使用してフィールドを追加し、投稿ページに表示できます。

インデックスからのページへのリンク

これで、各投稿ごとに新しいページを作成しましたが、インデックスページからこれらの投稿へのリンクを追加する必要があります。index.jsに移動し、コードを次のように変更して各投稿へのリンクを追加します。

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

export default ({ data }) => {
  return (
    <Layout>
      <SEO title="home" />
      <h1>My WordPress Blog</h1>
      <h4>Posts</h4>
      {data.allWordpressPost.edges.map(({ node }) => (
        <div>
          <Link to={node.slug}>
            <p>{node.title}</p>
          </Link>
          <div dangerouslySetInnerHTML={{ __html: node.excerpt }} />
        </div>
      ))}
    </Layout>
  )
}

export const pageQuery = graphql`
  query {
    allWordpressPost(sort: { fields: [date] }) {
      edges {
        node {
          title
          excerpt
          slug
        }
      }
    }
  }

これで、インデックスページは次のとおりになりました。

投稿へのリンクを追加した後のインデックスページ
投稿へのリンクを追加した後のインデックスページ

投稿へのリンクをクリックすると、blog-post.jsによってレンダリングされるブログ投稿ページが表示されます。

タイトル、コンテンツ、作成日、作成¥者がひぃうじされるブログ投稿
タイトル、コンテンツ、作成日、作成¥者がひぃうじされるブログ投稿

ステップ4:詳細な移行タスク

これですべてのWordPress投稿を正常にインポートできましたが、詳細設定を行い、今後も問題が発生しないようにします。このセクションでは、画像の最適化と、データに最終更新日のタイムスタンプを追加する方法について説明します。

画像パスの変換

オリジナルの投稿の1つである「Post with Image!」には画像がありました。同じページをGatsbyで確認すると、画像が表示されますが、画像の場所はWordPressの投稿と同じです。この例では、ローカルでホストされているWordPressの画像でます。

Gatsby投稿の画像とその場所
Gatsby投稿の画像とその場所

画像を外部でホストしている場合、同じ画像サーバーを指すため、これは問題になりません。ただし、WordPressインストール内に画像を保存する場合は、画像も移動しなければなりません!

Inline imagesプラグインを使用しましょう。まず、
gatsby-imageをインストールして、gatsby-wordpress-inline-imagesプラグインをインストールします。

npm install gatsby-image
npm install gatsby-wordpress-inline-images

次に、gatsby-config.jsファイルに次を追加します。

module.exports = {
  siteMetadata: {
    ...
  },
  plugins: [
    ...
    {
      resolve: `gatsby-source-wordpress`,
      options: {
        ...
        // If useACF is true, then the source plugin will try to import the WordPress ACF Plugin contents.
        // This feature is untested for sites hosted on WordPress.com
        useACF: true,
        plugins: [
          {
            resolve: `gatsby-wordpress-inline-images`,
            options:
            {
              baseUrl: `localhost:8888/wordpress`,
              protocol: `http`
            }
          }
        ]
      }
    }
  ],
}

上記の変更を行った後に開発サーバーを再起動すると、WordPressサイトから画像がダウンロードされ、ローカルに保存されます。保存場所を確認するには、同じ画像のパスを確認しましょう。

最終更新日を表示

定期的に投稿を更新するブログを運営している場合、投稿の最終更新日を表示したい場合があります。GraphQLクエリを使用して既に「作成日」を引き出しましたが、このセクションでは「最終更新日」のタイムスタンプの追加方法も説明します。

WordPressの「最終更新日」タイムスタンプをGatsby投稿に追加するには、変更されたフィールドをGraphQLクエリのアイテムのリストに追加する必要があります。これはdateのようなタイムスタンプであるため、formatStringパラメータも追加する必要があります。変更されたblog-post.jsファイルは次のとおりです。

...
<Layout>
  <div>
    ...
    <p> On: {post.date} </p>
    <p> Last modified: {post.modified} </p>
  </div>
</Layout>
...

export const query = graphql`
  query($slug: String!) {
  {
    allWordpressPost {
      edges {
        node {
          ...
          modified(formatString: "MM-DD-YYYY")
        }
      }
    }
  }

これを追加すると、Gatsbyのブログ投稿ページで「最終更新日」のタイムスタンプが表示されるようになります。

「最終更新日」のタイムスタンプのある投稿
「最終更新日」のタイムスタンプのある投稿

まとめ

WordPressサイトをGatsbyの静的サイトに変換することは、難しい作業です。変換の際に次の手順に従います。

  • Gatsbyをインストールしてスターターサイトを構築する
  • GraphQLを使用してGatsbyをWordPressに接続する
  • ブログ投稿用のテンプレートを作成する
  • WordPressのすべての画像をインポートする
  • WordPressの「最終更新日」タイムスタンプを表示する

さて、あなたはGatsbyを試してみたことがありますか?どう思いましたか?コメントでも書いて、ご意見をお寄せください。

Shaumik Daityari

Shaumik is a data analyst by day, and a comic book enthusiast by night (or maybe, he's Batman?) Shaumik has been writing tutorials and creating screencasts for over five years. When not working, he's busy automating mundane daily tasks through meticulously written scripts!