Gatsby.js×ContentfulをSurgeにデプロイする

7/14/2020

やること

Contentfulで管理している技術ブログの記事サムネ・タイトルのみを
Surgeにデプロイした静的サイトから参照する。

一部既存リソースの参照をゴールとして記事の内容までは表示していません。
応用すれば記事のbodyを取ってきてちゃんとしたブログも立ち上げ可能かと思います。

完成したもの

Gatsby Remo Work

gatsby_remo_work

NetlifyでデプロイしているNuxt.jsでもContentfulを使用しているので
同じリソースの画像・記事タイトル・記事内容を取ってこれます。

Gatsby.js

React Nativeベースの静的サイトジェネレータ。
Jamstack構成でよく使用され、Next.js等と比較しても欧米では一番流行っているフレームワークです。
内部でgraphqlを使用しています。

Contentful

Headless CMS。
ブログ記事のデータのみを管理して、表示するhtml等はGatsby側で管理。

Surge

無料で使える静的サイトホスティングサービス。
Surge.sh


Contentfulにリソースを作成

Contentful_resource

予め上メニューの Space Home から blog Space を作成。
Content Model > Add content type > Fileds に上記のような項目を追加する。

Gatsbyでアプリ作成

$ npm install -g gatsby-cli
$ gatsby new blog
$ cd gatsby
$ gatsby develop

localhost:8000 にアクセスするとStart Pageが表示されます。

APIキーを取得する

Contentful > Settings > API Keys > Example Key 1

Space ID
Content Delivery API - access token

この2つを控えます(Content Preview API - access tokenは使わない)

ローカルでデータを確認する

Gatsbyからcontentfulを使うように以下を追加。

$ npm install --save gatsby-source-contentfule

プロジェクトのディレクトリ直下に.envファイルを作成。

$ spaceId=xxxxxxxxxxxxx
$ accessToken=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

gatsby-config.jsの先頭に追記

const dotenv = require("dotenv")

if (process.env.ENVIRONMENT !== "production") {
  dotenv.config()
}

下の方にコメントが複数行があるので、真下にgatsby-source-contentfulの項目を追加する

// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// `gatsby-plugin-offline`,
    {
      resolve: "gatsby-source-contentful",
      options: {
        spaceId: process.env.spaceId,
        accessToken: process.env.accessToken,
      },
    },

src/pages/index.jsを修正

import React from "react"

// 追加
import { useStaticQuery, graphql, Link } from "gatsby"

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

const IndexPage = () => {
  // 追加
  const data = useStaticQuery(graphql`
    query allContentfulBlogPost(sort: { fields: [publishedAt], order: DESC }) {
      allContentfulBlogPost {
        nodes {
          title
          headerImage {
            resolutions(width: 1600, height: 1600) {
              src
            }
          }
          slug
        }
      }
    }
  `)
  return (
    <Layout>
      <SEO title="Home" />
        {/* queryで取得したデータを表示 */}
        {data.allContentfulBlogPost.nodes.map(({ title, slug, headerImage }) => (
          <div class="item">
            <figure class="cp_caption">
            <img src={headerImage.resolutions.src} alt="" class="card-img-top"></img>
              <figcaption>
                <h3>{title}</h3>
                <a href={`https://dev.remo.work/blog/${slug}`}></a>
              </figcaption>
            </figure>
          </div>
      ))}
    </Layout>
  )
}

ポイントとしては、Contentfulで定義したslugが使えるので
<a href={https://dev.remo.work/blog/${slug}}></a> で記事ごとに対応するリンクを貼っています。
またgraphqlでクエリする際に fields: [publishedAt], order: DESC を指定することで、常に最新記事がページの上に配置されるようにしています。
このallContentfulBlogPostの中でbodyやPublishedAtも取ってこれます(今回は使わないのでなし)
gatsby start でデータが確認できればOK。

Surgeにデプロイする

$ npm install --grobal surge
$ gatsby build

上記コマンドでsurgeをインストール後、アプリをbuildします。
その後、package.jsonのscripts項目にdeployを追加します。

"scripts": {
 .
 .
 .
  "deploy": "surge public/ https://[your domain name]/"
 },

すると gatsby deploy だけで指定ドメインでsurgeにデプロイできます。

$ gatsby deploy

初回実行時はコンソールからメールアドレスを登録して
受信したメールからVerifyする必要があったので、詰まったら公式サイトを参照。
Surge.sh

所感

今回は記事URLをNetlifyリソースにリンクしていますが、
gatsbyからContentfulのbodyもクエリできます。

これを使いSurgeでも記事が見れるようにしておけば、Netlifyが落ちても
Contentfulが生きていたらサイトが見れるといったホスティングサービスベースの冗長化ができます。

補足

gitでコード管理する際は.envをgitignoreしてください。

Wordpressの記事を取ってくるgatsby pluginもあるので、
Wordpressでブログ持ってる方は使ってみると面白そうです。
https://www.gatsbyjs.com/plugins/gatsby-source-wordpress/

©️ 2020 ふじい Dev-Remo-Work.