DEVELOPMENT
目次
gatsby cloud 上でbuild・contentful 記事投稿し、aws s3でhostingする設定方法 昨年末(2019年末)に登場したGatsby Cloud!
これは、buildとhostingをしてくれるサービスですが、
gatsbyを使っている方の悩みとして、ページ数や画像等のmediaファイルが増えてくると、ビルドの時間がかかる。
そこで、これをGatsby Cloudに任せ、 さらにhedlessのcms(contentfulやcosmic 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プランで十分ですね
- スペース名を入力して作成します。
- このスペース名が各サイト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上の環境変数と同じ名前に合わせるためです。後に紹介します。)
-
- こちらのプラグインで、GraphQLでContentful上のデータをGatsby Generate時に取得しに行きます。
ContentfulでAPI keyからtokenやスペースIDを取得
- ContentfulのSettingメニューの「API Keys」
- Creteボタンより作成する
-
以下をメモる
- Space ID
- Derivery aceess token(Previewではない)
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」でレポジトリを限定してます。
- レポジトリとブランチの設定をします
- 次に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まで!
株式会社UKAI 代表取締役CEO。建築を専攻していたが、新卒でYahoo!Japanにエンジニアとして入社。その後、転職、脱サラ、フリーランスエンジニアを経て、田舎へ移住し、ゲストハウスの開業、法人成り。ゲストハウス2軒、焼肉店、カフェ、食品製造業を運営しています。詳細はこちらから