What's?

Home / Gatsby cloud 上でbuild・Contentful(Headless CMS)で 記事投稿、管理し、AWS S3でhostingする方法

Gatsby cloud 上でbuild・Contentful(Headless CMS)で 記事投稿、管理し、AWS S3でhostingする方法
April 26, 2020

DEVELOPMENT

web
aws
s3
js
Gatsby
Clontentful
cms
gatsby-cloud

gatsby cloud 上でbuild・contentful 記事投稿し、aws s3でhostingする設定方法 昨年末(2019年末)に登場したGatsby Cloud

これは、buildとhostingをしてくれるサービスですが、

gatsbyを使っている方の悩みとして、ページ数や画像等のmediaファイルが増えてくると、ビルドの時間がかかる。

そこで、これをGatsby Cloudに任せ、 さらにhedlessのcmscontentfulcosmic js など)にて、記事を管理し、 リアルタイムpreviewまでも可能にし、

更に更にhosting先にawsやgcp使ってた場合、設定すればそのまま公開までできるという素晴らしさ!

これらの設定方法はまだ英語の記事しかなかったのですが、なんとか設定でき、運用開始できたので、ご紹介します。

はじめに(ご注意!)

  • こちらの導入は、現状GatsbyJSで fileでmarkdown方式で記事データがある場合、Contentfulにて記事管理する形にプロジェクト内色々と改修が必要です。
  • 現状のGatsbyJSのプロジェクトの記事データとContentfulが連動されるわけでは有りませんのでそこは期待してはいけません。
  • まずは、.mdファイルでの記事をすべてContentfulへimportする必要があります。
  • ContentfulのAPIでimport可能なようですが、形式が複雑だったのでよく見てません。方法はこの辺に記載があります。⬇

  • 2020/04/20現時点で設定した内容となり、ご自身のタイミングや環境で動かない可能性もありますので、ご注意下さい。
  • あくまで、ご自身の責任でご自身の判断で行って下さい。(なにか問題があっても一切の責任は負えません)

前提

  • 既にGatsbyJSで作成したプロジェクトを持っている
  • Headless CMSや静的サイトジェネレーター、GatsbyCloudについてはこちらを見て下さい。

この記事の内容を読むメリット

  • Gatsbyのbuild時間が短縮できる
  • リリース管理ができる
  • ソースコード側と、コンテンツ側を切り離せる(コード修正は、githubにcommit、コンテンツはHeadless CMSで(ここではContentful))
  • AWS(GCPや他の場所にも可能)にhosting

具体的に

  • GithubにCommitすれば、ビルドされデプロイされる
  • Contentful(Headless CMS)で記事を投稿する際に、リアルタイムでPreviewできる
  • 記事投稿しpublishすると、ビルドが開始されデプロイされる
  • ビルド時間(リリース作業)がローカルでやるより断然早くなる

手順

Contentfulサインアップと設定

  • Contentfulに行き、サインアップします。
  • スペースを作成します。

    • Freeプランで十分ですね capture3
    • スペース名を入力して作成します。
    • このスペース名が各サイト1つづつという感じですね。サイトと1対1です

contentfulについて

  • Space = サイト
  • Model = 動的にしたい部分。今回は記事
  • Modelのフィールド、入力する内容(titleやimage descriptionなど)
  • Content がモデルの実際のレコードです(各記事)という感じ
  • Mediaは、各モデルが使用する画像ファイルなど

Modelの作成

  • 記事用のモデルを作成します。
  • Contentfulにブログ記事モデルを作成していこうこちらの記事が詳しく記載あります。
  • 例)Model名:「BlogPost」、Field:「title, date, description, coverImage, avatarImage, category, tags, sulg, body」こんな所でしょうか
  • そして、コンテンツを試しに登録して、publishしておきます。

Gatsby プロジェクトに contentfulのpluginを設定

Gatsbyはもともと各CMSへの連動が可能です。この設定をし、contentfulでの記事管理を可能にします

  • dotnev(Contentfulの環境変数を設定するのに使います。Gatsby Build上の環境変数と同じ名前に合わせるためです。後に紹介します。)
  • gatsby-source-contentful

    • こちらのプラグインで、GraphQLでContentful上のデータをGatsby Generate時に取得しに行きます。

ContentfulでAPI keyからtokenやスペースIDを取得

  • ContentfulのSettingメニューの「API Keys」
  • Creteボタンより作成する capture4
  • 以下をメモる

    • Space ID
    • Derivery aceess token(Previewではない) capture5

gatsby-config.js

require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`,
})
~
~
.
module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: process.env.CONTENTFUL_SPACE_ID,
        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
        host: process.env.CONTENTFUL_HOST || `cdn.contentful.com`,
      },
    },
  ],
}
  • dotenvの環境変数名はこの名前で統一します(Gatsby Cloud上連携後、この環境変数名で登録されるため合わせる)

dotenvを設定

  • .env.development

    CONTENTFUL_SPACE_ID=xxxxxxxxxxxx
    CONTENTFUL_ACCESS_TOKEN=xxxxxxxxxxxxxx
    CONTENTFUL_HOST=preview.contentful.com
  • productionはここ(local)で参照することはないから不要(Gatsby Cloud上でBuildされるから)

Contentfulからデータ取得GraphQL

  • gatsby-node.js
const fs = require('fs')
const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions

  const blogPost = path.resolve(`./src/templates/blog-post.js`)
  const result = await graphql(
    `
      {
        allContentfulBlogPost( // allContentfulモデル名(キャメルケース)となる
          sort: { fields: [date], order: DESC }
          limit: 1000
        ) {
          edges {
            node {
              title
              slug
            }
          }
        }
      }
    `
  )

  if (result.errors) {
    throw result.errors
  }

  // Create blog posts pages.
  const posts = result.data.allContentfulBlogPost.edges

  posts.forEach((post, index) => {
    createPage({
      path: post.node.slug,
      component: blogPost,
      context: {
        slug: post.node.slug
      },
    })
  })
}
/* ここは不要になる
exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}
*/
  • index.js
allContentfulBlogPost(sort: { fields: [date], order: DESC }) {
  edges {
    node {
      slug // text pathタイプ
      date(formatString: "MMMM DD, YYYY") // 日付
      title // sort text
      description // long text
      category { // relation category model
        name
      }
      avatar { // image
        fixed(width: 50, height: 50) {
          ...GatsbyContentfulFixed_tracedSVG
        }
      }
      cover { // image
        fluid(maxWidth: 1000, quality: 90) {
          ...GatsbyContentfulFluid_tracedSVG
        }
      }
      body { // rich text
        json // jsonで
      }
    }
  }
}
  • blogPost.js 単品で取るときはこういうクエリ名

    contentfulBlogPost(slug: { eq: $slug }) {
    ~
    ~
    }
  • richtextの変換は、reactComponentやHTMLに変換できるものがContentfulで用意されています
  • Rendering Contentful Rich Text with Javascript この辺を参考にしていただけるといいと思います。
  • 記事中の画像の扱いは難しそうなのですが、Github この辺が参考になりそうです

コードをGithubへ

Githubでソースコード管理していない場合は、レポジトリ作成し、commitしましょう!

$ git remote add origin git@github.com:xxxxxxx/xxxxxx.git
$ git add
$ git commit -m "first commit"
$ git push origin master

ビルド対象のレポジトリは後ほど、GatsbyCloudで設定可能です

Gatsby Cloudにサインイン

  • Gatsbyjs.comから「Get started for free」し、サインアップ&インします

    • ※Githubアカウント等でサインイン可能です
  • 次のページで、「I already have a Gatsby site」を選択
  • 「First name」や「Last name」、「Work email」を入力して、next
  • 「Select Destination」で、githubとの連携画面が表示されるので、連携します

    • 僕は「Only select repositories」でレポジトリを限定してます。 capture1
  • レポジトリとブランチの設定をします capture2
  • 次にOptional Integrationの、「Contentful」のConnectを押すと、ログインし、スペースの選択となりますので、Connectします。
  • これでOKです。早速ビルドが始まります。
  • ProductionとPreviewそれぞれ、hostingURLが記載されています。

Gatsby Cloud側のAPI KeyのDeliveryのAccesstoken変更する

  • 【重要】Preivew側のAccessTokeを先程作成した、Delivary用のAccesstokenにします

この時、以下の3つの設定が一致していないといけません

  • Gatsbyjsプロジェクト内のgatsby-config.jsに記載(.env.development)のtoken
  • Gatsby Cloud上のsettingのtoken
  • ContentfulのAPI keyのtoken

Contentful側でPreviewの設定をします

Gatsby CloudのSetting Envarriament 記載のPreviewのAccess tokenをメモります

  • ContentfulのAppメニューから、Gatsby Cloudを選択します
  • メモったaccess token を設定します これで、Contentfulで記事投稿中に右のメニューにpreviewボタンが現れ、リアルタイムPreviewが出来るはずです

S3へのDeploy設定

  • Hostingの設定からAmazon S3を選択すると、AWSのAccess keyと、secret Keyの入力画面が出てくるので
  • 予め用意しておいたキーを入力すればOKです。

まとめ

結構たいへんでした。。 そもそも、GatsbyjsのファイルのデータをContentfulにimport出来ると最高ですが、無理みたいでした

ただ、一応これで、

  • Contentfulから記事を投稿したとき
  • githubにコミットした時

に、Buildeが開始され、完了後、deployされるのと、

Contentful上で記事作成時に、Previewが可能となりました。

これにより、フロント側と、バックエンド側が完全に切り離れ、記事の投稿等を非エンジニアでも行えるようになりました

コメントや疑問ありましたら、Twitterまで!

▶ 参考 Getting Started with Gatsby Cloud and Contentful

うかい / 株式会社UKAI
うかい@代表取締役兼エンジニア株式会社UKAI
Nobuyuki Ukai

株式会社UKAI 代表取締役CEO。建築を専攻していたが、新卒でYahoo!Japanにエンジニアとして入社。その後、転職、脱サラ、フリーランスエンジニアを経て、田舎へ移住し、ゲストハウスの開業、法人成り。ゲストハウス2軒、焼肉店、カフェ、食品製造業を運営しています。詳細はこちらから

🙏よかったらシェアお願いします🙏
WRITTEN BY
うかい / 株式会社UKAI
うかい@代表取締役兼エンジニア株式会社UKAI

Nobuyuki Ukai

株式会社UKAI 代表取締役CEO。建築を専攻していたが、新卒でYahoo!Japanにエンジニアとして入社。その後、転職、脱サラ、フリーランスエンジニアを経て、田舎へ移住し、ゲストハウスの開業、法人成り。ゲストハウス2軒、焼肉店、カフェ、食品製造業を運営しています。詳細はこちらから

CONACT
入力して下さい
Slack からもどうぞ

※お気軽にどうぞ!(6月20日まで有効!お早めに)

COPYRIGHT © 2020 UKAI CO., LTD. ALL RIGHTS RESERVED.