tag:crieit.net,2005:https://crieit.net/tags/microCMS/feed
「microCMS」の記事 - Crieit
Crieitでタグ「microCMS」に投稿された最近の記事
2021-11-05T21:44:25+09:00
https://crieit.net/tags/microCMS/feed
tag:crieit.net,2005:PublicArticle/17741
2021-11-05T21:44:25+09:00
2021-11-05T21:44:25+09:00
https://crieit.net/posts/microcms-api-update-gatsby-update-20211106
microCMS の X-API-KEY リニューアルに合わせて Vercel の設定と Gatsby のプロジェクトを更新する
<p>メール通知で microCMS の X-API-KEY がリニューアルされたという通知を受け取って対応することにしました。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.microcms.io/renew-x-microcms-api-key/">APIキーをX-MICROCMS-API-KEYへとリニューアルしました。 | microCMSブログ</a></li>
</ul>
<blockquote>
<p>従来のX-API-KEY, X-WRITE-API-KEY, X-DRAFT-KEYは統合され、X-MICROCMS-API-KEYに変更となります。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://blog.microcms.io/renew-x-microcms-api-key/">APIキーをX-MICROCMS-API-KEYへとリニューアルしました。 | microCMSブログ</a></p>
</blockquote>
<p>とのことなので、これに対応することにします。</p>
<h2 id="microCMS"><a href="#microCMS">microCMS</a></h2>
<p>まずは microCMS 側の作業。新しいAPIキーを発行し直します。</p>
<p><a href="https://crieit.now.sh/upload_images/b639bdef8b9834d65ed80dcb79d999e46185263f658dd.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b639bdef8b9834d65ed80dcb79d999e46185263f658dd.jpg?mw=700" alt="APIキーの一覧" /></a></p>
<p>「APIキー管理」のAPIキーの一覧で「旧X-API-KEY」があることを確認。</p>
<p><a href="https://crieit.now.sh/upload_images/6adc5584ea41a4d7620ea61147890b1261852649a9f13.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6adc5584ea41a4d7620ea61147890b1261852649a9f13.jpg?mw=700" alt="APIキーの詳細" /></a></p>
<p>選択して詳細画面から「削除」を選択。</p>
<p>続いて新しいAPIキーを発行し直します。</p>
<p><a href="https://crieit.now.sh/upload_images/eef5b0f7a42cda381863a3eae0f6894361852651849ef.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/eef5b0f7a42cda381863a3eae0f6894361852651849ef.jpg?mw=700" alt="新X-MICROCMS-API-KEYの発行" /></a></p>
<p>X-MICROCMS-API-KEY を発行します。今回はAPI経由では参照しかしないので GET のみの権限とします。</p>
<p><a href="https://crieit.now.sh/upload_images/8febcc76cb4c74b656c4720ed16f44a06185265a7d678.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8febcc76cb4c74b656c4720ed16f44a06185265a7d678.jpg?mw=700" alt="APIキーをコピー" /></a></p>
<p>発行されたAPIキーをコピーして控えます。</p>
<p>これで microCMS 側の作業は完了です。</p>
<h2 id="Vercel"><a href="#Vercel">Vercel</a></h2>
<p>続いて Vercel にログインします。</p>
<p><a href="https://crieit.now.sh/upload_images/1ae9a58b4f0e8ee01d8a591c1629ff9b618526623540c.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1ae9a58b4f0e8ee01d8a591c1629ff9b618526623540c.jpg?mw=700" alt="Vercel の環境変数の一覧" /></a></p>
<p>プロジェクトの「Settings」から「Enviroment Variables」に進みます。</p>
<p><a href="https://crieit.now.sh/upload_images/3a0751306ac22bdcc1333827ce44d7f16185266ada888.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3a0751306ac22bdcc1333827ce44d7f16185266ada888.jpg?mw=700" alt="API_KEYの変更" /></a></p>
<p><code>API_KEY</code>の値を先ほど控えた値に変更します。</p>
<p>これでOKかと思ったのですが……。</p>
<pre><code class="bash">00:03:22.489 error microCMS API ERROR:
00:03:22.489 statusCode: 401
00:03:22.489 message: X-MICROCMS-API-KEY header is invalid.
00:03:22.492 not finished source and transform nodes - 1.046s
00:03:23.631 Error: Command "npm run build" exited with 1
</code></pre>
<p>ビルドログを見ると 401エラー でコケていますね。認証に失敗しているようです。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://vanilla-note.com/posts/gatsby4-1-microcms-3/">microCMSの新しいX-MICROCMS-API-KEYに対応する | Vanilla note</a></li>
</ul>
<p>検索すると、 Gatsby の microCMS 連携のパッケージも更新しないといけないとのこと。</p>
<h2 id="Gatsby プロジェクト"><a href="#Gatsby+%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88">Gatsby プロジェクト</a></h2>
<p>そこで該当パッケージのバージョンをアップデートします。</p>
<pre><code class="json"> "dependencies": {
// 略
"gatsby-source-microcms": "^1.2.1",
// 略
}
</code></pre>
<p><code>gatsby-source-microcms</code> を</p>
<pre><code class="json"> "dependencies": {
// 略
"gatsby-source-microcms": "^2.0.0",
// 略
}
</code></pre>
<p><code>2.0.0</code> にアップデート。</p>
<p>これでビルドを走らせ、正常に完了することを確認しました。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.microcms.io/renew-x-microcms-api-key/">APIキーをX-MICROCMS-API-KEYへとリニューアルしました。 | microCMSブログ</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://vanilla-note.com/posts/gatsby4-1-microcms-3/">microCMSの新しいX-MICROCMS-API-KEYに対応する | Vanilla note</a></li>
</ul>
<p>Vercel に関しては自分の過去の記事も参考にして辿りつつ……。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2021/08/29/gatsby-vercel-microcms-cooprate-2/">Gatsby.js + Vercel + microCMS の JAMStack 環境を構築する – Ewig Leere(Lab2)</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/17623
2021-08-29T00:49:34+09:00
2021-08-29T00:49:34+09:00
https://crieit.net/posts/gatsby-vercel-microcms-cooprate-20210829-2
Gatsby.js + Vercel + microCMS の JAMStack 環境を構築する
<p><a href="https://crieit.net/posts/gatsby-vercel-microcms-cooprate-20210829-1">microCMS の設定が完了した</a>ので、次は microCMS からデータを取得するように Gatsby.js の方に手を入れます。また、 microCMS と Vercel に設定を加えて連携させ、 Gatsby.js + Vercel + microCMS の JAMStack 環境を構築します。</p>
<h2 id="改修"><a href="#%E6%94%B9%E4%BF%AE">改修</a></h2>
<p>今回は<a target="_blank" rel="nofollow noopener" href="https://www.gatsbyjs.com/starters/renyuanz/leonids">leonids: Gatsby Starter | Gatsby</a>を使用しているので、その前提で。</p>
<p>テーマが変わったり、 microCMS のスキーマが変われば諸々の調整が必要となります。</p>
<h3 id="パッケージの追加"><a href="#%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E8%BF%BD%E5%8A%A0">パッケージの追加</a></h3>
<pre><code class="bash">> yarn add yarn add gatsby-source-microcms
## 略
Done in 231.79s.
> yarn add marked
## 略
Done in 7.30s.
</code></pre>
<p>今回は microCMS を利用するので <code>gatsby-source-microcms</code> を追加します。また、本文コンテンツは Markdown で記述しているのですが Gatsby.js の自前の Markdownパーサ まで手が届かなかったので安直に <code>marked</code> を使いました。</p>
<p>それから、内部的には <code>dotenv</code> も使用していますが <code>yarn.lock</code> を見たら既に入っていたので追加はしていません。</p>
<h3 id="gatsby-config.js"><a href="#gatsby-config.js">gatsby-config.js</a></h3>
<p>さて、改修の最初は Gatsby.js の設定から。</p>
<pre><code class="javascript">module.exports = {
// 略
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/content/blog`,
name: `blog`,
},
},
// 略
},
`gatsby-plugin-feed`,
{
// 略
],
// 略
}
</code></pre>
<p>これを以下のように修正。</p>
<pre><code class="js">const activeEnv = process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV
if(activeEnv === "development") {
require("dotenv").config({
path: `.env.${activeEnv}`,
})
}
module.exports = {
// 略
plugins: [
{
resolve: 'gatsby-source-microcms',
options: {
apiKey: process.env.API_KEY,
serviceId: process.env.SERVICE_ID,
apis: [{
endpoint: process.env.APIS_ENDPOINT,
}],
},
},
// 略
{
resolve: `gatsby-plugin-feed`,
options: {
query: `
{
site {
siteMetadata {
title
description
siteUrl
}
}
}
`,
feeds: [
{
serialize: ({ query: { site, allMicrocmsHogeHogeBlog } }) => {
return allMicrocmsHogeHogeBlog.edges.map(edge => {
return Object.assign({}, edge.node, {
description: edge.node.keywords,
date: edge.node.date,
url: site.siteMetadata.siteUrl + edge.node.slug,
guid: site.siteMetadata.siteUrl + edge.node.slug,
custom_elements: [{ "content:encoded": edge.node.body }],
})
})
},
query: `
{
allMicrocmsHogeHogeBlog(sort: {fields: [date], order: DESC}) {
totalCount
pageInfo {
perPage
pageCount
}
edges {
node {
body
createdAt
date
id
keywords
publishedAt
revisedAt
slug
title
updatedAt
}
}
}
}
`,
output: "/rss.xml",
title: "HogeHoge Blog's RSS Feed",
},
],
},
},
// 略
],
// 略
}
</code></pre>
<p>変更点は以下。</p>
<ul>
<li>ローカルのファイルをコンテンツのリソース参照先としていたのを microCMS をリソースとするように修正</li>
<li><code>gatsby develop</code> 時は問題なかったのですが、 <code>gatsby build</code> 時に RSSフィードを生成する <code>gatsby-plugin-feed</code>プラグイン が通常の Markdown の構成をデフォルトにしており、 microCMS に置き換えたことでデータスキーマが異なるとエラーになってしまいました (本番ビルド時に気付いた)。
<ul>
<li>そこで、 <code>gatsby-plugin-feed</code>プラグイン の GraphQL も今回定義した microCMS のスキーマに沿って変更しました。併せて <code>serialize</code>メソッド の中身もスキーマに合わせて調整。</li>
</ul></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.gatsbyjs.com/plugins/gatsby-source-microcms/">gatsby-source-microcms | Gatsby</a>のサンプルコードでは Git 管理下になる <code>gatsby-config.js</code> に APIキー 等の情報がそのままベタ書きになってしまうので、 <code>dotenv</code> で外部ファイルに取り出すことで隠蔽しました
<ul>
<li>後述しますが、 Vercel の環境変数も <code>process.env</code> で渡ってくるので、<code>development</code> の場合は <code>dotenv</code> 経由の外部ファイルをパラメータのリソースに、 <code>production</code> の場合は Vercel の環境変数をリソースとするように書き分けました</li>
</ul></li>
</ul>
<h3 id="gatby-node.js"><a href="#gatby-node.js">gatby-node.js</a></h3>
<pre><code class="javascript">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(
`
{
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
limit: 1000
) {
edges {
node {
fields {
slug
}
frontmatter {
title
}
}
}
}
}
`
)
if (result.errors) {
throw result.errors
}
// Create blog posts pages.
const posts = result.data.allMarkdownRemark.edges
posts.forEach((post, index) => {
const previous = index === posts.length - 1 ? null : posts[index + 1].node
const next = index === 0 ? null : posts[index - 1].node
createPage({
path: post.node.fields.slug,
component: blogPost,
context: {
slug: post.node.fields.slug,
previous,
next,
},
})
})
// Create blog post list pages
const postsPerPage = 5
const numPages = Math.ceil(posts.length / postsPerPage)
Array.from({ length: numPages }).forEach((_, i) => {
createPage({
path: i === 0 ? `/` : `/${i + 1}`,
component: path.resolve("./src/templates/blog-list.tsx"),
context: {
limit: postsPerPage,
skip: i * postsPerPage,
numPages,
currentPage: i + 1,
},
})
})
}
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode })
createNodeField({
name: `slug`,
node,
value,
})
}
}
</code></pre>
<p>これを以下のように修正。</p>
<pre><code class="javascript">const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
const result = await graphql(
`
{
allMicrocmsHogeHogeBlog(sort: {fields: [date], order: DESC}) {
totalCount
pageInfo {
perPage
pageCount
}
edges {
node {
body
createdAt
date
id
keywords
publishedAt
revisedAt
slug
title
updatedAt
}
}
}
}
`
)
if (result.errors) {
throw result.errors
}
// Create blog posts pages.
const posts = result.data.allMicrocmsHogeHogeBlog.edges
result.data.allMicrocmsHogeHogeBlog.edges.forEach((post, index) => {
const previous = index === posts.length - 1 ? null : posts[index + 1].node
const next = index === 0 ? null : posts[index - 1].node
createPage({
path: post.node.slug,
component: path.resolve('./src/templates/blog-post.js'),
context: {
slug: post.node.slug,
previous,
next,
},
});
});
// Create blog post list pages
const postsPerPage = result.data.allMicrocmsHogeHogeBlog.pageInfo.limit || 10
const numPages = Math.ceil(result.data.allMicrocmsHogeHogeBlog.totalCount / postsPerPage)
console.log(result.data.allMicrocmsHogeHogeBlog.totalCount, postsPerPage)
Array.from({ length: numPages }).forEach((_, i) => {
createPage({
path: i === 0 ? `/` : `/${i + 1}`,
component: path.resolve("./src/templates/blog-list.tsx"),
context: {
limit: postsPerPage,
skip: i * postsPerPage,
numPages,
currentPage: i + 1,
},
})
})
}
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions
if (node.internal.type === `microcmsHogeHogeBlog`) {
const value = createFilePath({ node, getNode })
createNodeField({
name: `slug`,
node,
value,
})
}
}
</code></pre>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.gatsbyjs.com/plugins/gatsby-source-microcms/">gatsby-source-microcms | Gatsby</a>のサンプルコードはシンプル過ぎて GraphQL初心者には分かりづらかったので、 <code>gatsby develop</code> で起動した <code>http://localhost:8000/___graphql</code> の GraphQL を試すGUIでひたすらAPIを叩いてパラメータを変えたりしてどういう GraphQL を作れば望んだレスポンスを得られるか確認しながら地道に調整していきました</li>
<li>ベースのコードをなるべく変えないように調整して、各種プロパティの階層等を調整しました</li>
<li><code>MarkdownRemark</code> や <code>allMarkdownRemark</code> が Markdownファイル をリソースとする場合のキーのような働きをしているのが分かったので、それを <code>http://localhost:8000/___graphql</code> で表示された microCMS のキーに変更したり</li>
</ul>
<p>GraphQL の構造やレスポンスに慣れるまで時間がかかりましたが、最終的には <code>http://localhost:8000/___graphql</code> であれこれ試したのが一番効果がありました。</p>
<h3 id="blog-list.tsx"><a href="#blog-list.tsx">blog-list.tsx</a></h3>
<p>記事一覧ページ。トップページもこのテンプレートから生成されています。</p>
<pre><code class="javascript">// Gatsby supports TypeScript natively!
import React from "react"
import { PageProps, Link, graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { rhythm } from "../utils/typography"
type PageContext = {
currentPage: number
numPages: number
}
type Data = {
site: {
siteMetadata: {
title: string
}
}
allMarkdownRemark: {
edges: {
node: {
excerpt: string
frontmatter: {
title: string
date: string
description: string
}
fields: {
slug: string
}
}
}[]
}
}
const BlogIndex = ({
data,
location,
pageContext,
}: PageProps<Data, PageContext>) => {
const siteTitle = data.site.siteMetadata.title
const posts = data.allMarkdownRemark.edges
const { currentPage, numPages } = pageContext
const isFirst = currentPage === 1
const isLast = currentPage === numPages
const prevPage = currentPage - 1 === 1 ? "/" : `/${currentPage - 1}`
const nextPage = `/${currentPage + 1}`
return (
<Layout location={location} title={siteTitle}>
<SEO title="All posts" />
{posts.map(({ node }) => {
const title = node.frontmatter.title || node.fields.slug
return (
<article key={node.fields.slug}>
<header>
<h3
style=<span>{</span><span>{</span>
marginBottom: rhythm(1 / 4),
<span>}</span><span>}</span>
>
<Link style=<span>{</span><span>{</span> boxShadow: `none` <span>}</span><span>}</span> to={node.fields.slug}>
{title}
</Link>
</h3>
<small>{node.frontmatter.date}</small>
</header>
<section>
<p
dangerouslySetInnerHTML=<span>{</span><span>{</span>
__html: node.frontmatter.description || node.excerpt,
<span>}</span><span>}</span>
/>
</section>
</article>
)
})}
<nav>
<ul
style=<span>{</span><span>{</span>
display: `flex`,
flexWrap: `wrap`,
justifyContent: `space-between`,
listStyle: `none`,
padding: 0,
<span>}</span><span>}</span>
>
<li>
{!isFirst && (
<Link to={prevPage} rel="prev">
← Previous Page
</Link>
)}
</li>
<li>
{!isLast && (
<Link to={nextPage} rel="next">
Next Page →
</Link>
)}
</li>
</ul>
</nav>
</Layout>
)
}
export default BlogIndex
export const pageQuery = graphql`
query blogPageQuery($skip: Int!, $limit: Int!) {
site {
siteMetadata {
title
}
}
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
limit: $limit
skip: $skip
) {
edges {
node {
excerpt
fields {
slug
}
frontmatter {
date(formatString: "MMMM DD, YYYY")
title
description
}
}
}
}
}
`
</code></pre>
<p>これを以下のように改修。</p>
<pre><code class="javascript">// Gatsby supports TypeScript natively!
import React from "react"
import { PageProps, Link, graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { rhythm } from "../utils/typography"
type PageContext = {
currentPage: number
numPages: number
}
type Data = {
site: {
siteMetadata: {
title: string
}
}
allMicrocmsHogeHogeBlog: {
edges: {
node: {
id: string
keywords: string
title: string
updatedAt: string
slug: string
revisedAt: string
publishedAt: string
date: string
createdAt: string
body: string
}
}[]
}
}
const BlogIndex = ({
data,
location,
pageContext,
}: PageProps<Data, PageContext>) => {
const siteTitle = data.site.siteMetadata.title
const posts = data.allMicrocmsHogeHogeBlog.edges
const { currentPage, numPages } = pageContext
const isFirst = currentPage === 1
const isLast = currentPage === numPages
const prevPage = currentPage - 1 === 1 ? "/" : `/${currentPage - 1}`
const nextPage = `/${currentPage + 1}`
return (
<Layout location={location} title={siteTitle}>
<SEO title="All posts" />
{posts.map(({ node }) => {
const title = node.title || node.slug
return (
<article key={node.slug}>
<header>
<h3
style=<span>{</span><span>{</span>
marginBottom: rhythm(1 / 4),
<span>}</span><span>}</span>
>
<Link style=<span>{</span><span>{</span> boxShadow: `none` <span>}</span><span>}</span> to={node.slug}>
{title}
</Link>
</h3>
<small>{node.date}</small>
</header>
<section>
<p
dangerouslySetInnerHTML=<span>{</span><span>{</span>
__html: node.keywords,
<span>}</span><span>}</span>
/>
</section>
</article>
)
})}
<nav>
<ul
style=<span>{</span><span>{</span>
display: `flex`,
flexWrap: `wrap`,
justifyContent: `space-between`,
listStyle: `none`,
padding: 0,
<span>}</span><span>}</span>
>
<li>
{!isFirst && (
<Link to={prevPage} rel="prev">
← Previous Page
</Link>
)}
</li>
<li>
{!isLast && (
<Link to={nextPage} rel="next">
Next Page →
</Link>
)}
</li>
</ul>
</nav>
</Layout>
)
}
export default BlogIndex
export const pageQuery = graphql`
query blogPageQuery($skip: Int!, $limit: Int!) {
site {
siteMetadata {
title
}
}
allMicrocmsHogeHogeBlog(
sort: {fields: [date], order: DESC}
limit: $limit
skip: $skip
) {
edges {
node {
body
createdAt
date(formatString: "YYYY/MM/DD")
id
keywords
publishedAt
revisedAt
slug
title
updatedAt
}
}
}
}
`
</code></pre>
<p>ここは大々的な改修というよりは、 GraphQL の変更と、それに併せて変化したデータ構造に合わせてプロパティ名やチェーンを調整した感じです。</p>
<h3 id="blog-post.js"><a href="#blog-post.js">blog-post.js</a></h3>
<pre><code class="javascript">import React from "react"
import { Link, graphql } from "gatsby"
import Bio from "../components/bio"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { rhythm, scale } from "../utils/typography"
const BlogPostTemplate = ({ data, pageContext, location }) => {
const post = data.markdownRemark
// const siteTitle = data.site.siteMetadata.title
const { previous, next } = pageContext
return (
<Layout location={location} title="Home">
<SEO
title={post.frontmatter.title}
description={post.frontmatter.description || post.excerpt}
/>
<article>
<header>
<h1
style=<span>{</span><span>{</span>
marginBottom: 0,
<span>}</span><span>}</span>
>
{post.frontmatter.title}
</h1>
<p
style=<span>{</span><span>{</span>
...scale(-1 / 5),
display: `block`,
marginBottom: rhythm(1),
<span>}</span><span>}</span>
>
{post.frontmatter.date}
</p>
</header>
<section dangerouslySetInnerHTML=<span>{</span><span>{</span> __html: post.html <span>}</span><span>}</span> />
<hr
style=<span>{</span><span>{</span>
marginBottom: rhythm(1),
<span>}</span><span>}</span>
/>
<footer>
<Bio />
</footer>
</article>
<nav>
<ul
style=<span>{</span><span>{</span>
display: `flex`,
flexWrap: `wrap`,
justifyContent: `space-between`,
listStyle: `none`,
padding: 0,
<span>}</span><span>}</span>
>
<li>
{previous && (
<Link to={previous.fields.slug} rel="prev">
← {previous.frontmatter.title}
</Link>
)}
</li>
<li>
{next && (
<Link to={next.fields.slug} rel="next">
{next.frontmatter.title} →
</Link>
)}
</li>
</ul>
</nav>
</Layout>
)
}
export default BlogPostTemplate
export const pageQuery = graphql`
query BlogPostBySlug($slug: String!) {
site {
siteMetadata {
title
}
}
markdownRemark(fields: { slug: { eq: $slug } }) {
id
excerpt(pruneLength: 160)
html
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
description
}
}
}
`
</code></pre>
<p>これを以下のように改修。</p>
<pre><code class="javascript">import React from "react"
import { Link, graphql } from "gatsby"
import Bio from "../components/bio"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { rhythm, scale } from "../utils/typography"
import marked from "marked"
const BlogPostTemplate = ({ data, pageContext, location }) => {
const post = data.microcmsHogeHogeBlog
// const siteTitle = data.site.siteMetadata.title
const { previous, next } = pageContext
return (
<Layout location={location} title="Home">
<SEO
title={post.title}
description={post.keywords}
/>
<article>
<header>
<h1
style=<span>{</span><span>{</span>
marginBottom: 0,
<span>}</span><span>}</span>
>
{post.title}
</h1>
<p
style=<span>{</span><span>{</span>
...scale(-1 / 5),
display: `block`,
marginBottom: rhythm(1),
<span>}</span><span>}</span>
>
{post.date}
</p>
</header>
<section dangerouslySetInnerHTML=<span>{</span><span>{</span> __html: marked(post.body) <span>}</span><span>}</span> />
<hr
style=<span>{</span><span>{</span>
marginBottom: rhythm(1),
<span>}</span><span>}</span>
/>
<footer>
<Bio />
</footer>
</article>
<nav>
<ul
style=<span>{</span><span>{</span>
display: `flex`,
flexWrap: `wrap`,
justifyContent: `space-between`,
listStyle: `none`,
padding: 0,
<span>}</span><span>}</span>
>
<li>
{previous && (
<Link to={'../'+previous.slug} rel="prev">
← {previous.title}
</Link>
)}
</li>
<li>
{next && (
<Link to={'../'+next.slug} rel="next">
{next.title} →
</Link>
)}
</li>
</ul>
</nav>
</Layout>
)
}
export default BlogPostTemplate
export const pageQuery = graphql`
query BlogPostBySlug($slug: String!) {
site {
siteMetadata {
title
}
}
microcmsHogeHogeBlog(slug: { eq: $slug }) {
id
keywords
title
updatedAt
slug
revisedAt
publishedAt
date(formatString: "YYYY/MM/DD")
createdAt
body
}
}
`
</code></pre>
<p>こちらも <code>blog-list.tsx</code> と同様 GraphQL の変更とそれに伴うプロパティ名やチェーンの調整がメインです。本文の Markdown は冒頭の通り時短のため <code>marked</code> を使いました。</p>
<p>こうして見てみると、 GraphQL に慣れるまでかなり紆余曲折した気がするのですが、 <code>blog-list.tsx</code> や <code>blog-post.js</code> は特に出来上がったコードがあまり元から変化していませんね……。</p>
<h2 id="microCMS で APIキー を参照"><a href="#microCMS+%E3%81%A7+API%E3%82%AD%E3%83%BC+%E3%82%92%E5%8F%82%E7%85%A7">microCMS で APIキー を参照</a></h2>
<p>microCMS で APIキー を控えます。</p>
<p><a href="https://crieit.now.sh/upload_images/949bd68fc9e6b312266c6dd7d831ade5612a583ed1bd6.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/949bd68fc9e6b312266c6dd7d831ade5612a583ed1bd6.jpg?mw=700" alt="APIキーの取得" /></a></p>
<p>「サービス設定」→「APIキー」と進みます。今回必要なのは「X-API-KEY」。これを控えておきます。</p>
<h2 id="Vercel の設定"><a href="#Vercel+%E3%81%AE%E8%A8%AD%E5%AE%9A">Vercel の設定</a></h2>
<p>続いて Vercel の設定へ。</p>
<h3 id="環境変数の設定"><a href="#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AE%E8%A8%AD%E5%AE%9A">環境変数の設定</a></h3>
<p>まずは環境変数の設定。</p>
<p><a href="https://crieit.now.sh/upload_images/57a8cc2a08598bf78b631bbd9da2a024612a5842798b2.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/57a8cc2a08598bf78b631bbd9da2a024612a5842798b2.jpg?mw=700" alt="環境変数の設定" /></a></p>
<p>プロジェクトを選択後、「Settings」から「Enviroment Variables」へ。</p>
<p>「NAME」にコードに記載したキーの名前を付けて、実際の値を入力します。画面では APIキー なので上述の microCMS の管理画面で控えた APIキー を入力。</p>
<p><a href="https://crieit.now.sh/upload_images/3bbfd322b71fb32df23894afdd5853d5612a584583337.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3bbfd322b71fb32df23894afdd5853d5612a584583337.jpg?mw=700" alt="環境変数の設定2" /></a></p>
<p>他、必要な変数をセットします。</p>
<h3 id="Deploy Hooks を登録"><a href="#Deploy+Hooks+%E3%82%92%E7%99%BB%E9%8C%B2">Deploy Hooks を登録</a></h3>
<p>次に Deploy Hooks をひっかけます。</p>
<p>プロジェクトの「Settings」から今度は「Git」へ。</p>
<p><a href="https://crieit.now.sh/upload_images/4f89b78a73ad66c2fab07245a0b599ac612a58482a821.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/4f89b78a73ad66c2fab07245a0b599ac612a58482a821.jpg?mw=700" alt="Deploy hooks" /></a></p>
<p>Deploy Hooks に名前を入力、ブランチは通常は <code>main</code> になるかと。</p>
<p><a href="https://crieit.now.sh/upload_images/792d34407a2e1061c785101139250868612a584aeed86.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/792d34407a2e1061c785101139250868612a584aeed86.jpg?mw=700" alt="Deploy Hooks を控える" /></a></p>
<p>登録されたら Hook の URL を控えます。</p>
<h2 id="microCMS の設定"><a href="#microCMS+%E3%81%AE%E8%A8%AD%E5%AE%9A">microCMS の設定</a></h2>
<p>お次は microCMS の画面へ。</p>
<p><a href="https://crieit.now.sh/upload_images/16478a5b69bd9cb593abea925cd2c925612a584d45b74.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/16478a5b69bd9cb593abea925cd2c925612a584d45b74.jpg?mw=700" alt="Webhook" /></a></p>
<p>サービスの管理画面から「API設定」→「Webhook」へ。</p>
<p><a href="https://crieit.now.sh/upload_images/192e10d26803bfa0dcf31470a2553f63612a58505802c.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/192e10d26803bfa0dcf31470a2553f63612a58505802c.jpg?mw=700" alt="カスタム通知" /></a></p>
<p>Vercel は一覧にはないので「カスタム通知」を選択。</p>
<p><a href="https://crieit.now.sh/upload_images/b93547fbc6ca4f11e11986ec1869d7d5612a5853d80e0.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b93547fbc6ca4f11e11986ec1869d7d5612a5853d80e0.jpg?mw=700" alt="Vercel の Hook を設定" /></a></p>
<p>名前は任意の名前を。</p>
<p>Hook の URL に先ほど控えた URL を入力します。</p>
<p><a href="https://crieit.now.sh/upload_images/39693fd99f7447504a37a4bfd38afea0612a58568376c.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/39693fd99f7447504a37a4bfd38afea0612a58568376c.jpg?mw=700" alt="Hook の権限" /></a></p>
<p>権限はこのような感じ。基本的に公開されているデータに変更が加わったら Hook が通知を行うものとします。</p>
<h2 id="テスト投稿"><a href="#%E3%83%86%E3%82%B9%E3%83%88%E6%8A%95%E7%A8%BF">テスト投稿</a></h2>
<p><a href="https://crieit.now.sh/upload_images/58704ee832c977a18796e1a3e05c2c8f612a5859db3dd.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/58704ee832c977a18796e1a3e05c2c8f612a5859db3dd.jpg?mw=700" alt="記事を試しに追加" /></a></p>
<p>ここまで設定できたら、試しに記事を新しく追加してみます。</p>
<p><a href="https://crieit.now.sh/upload_images/b79d4f2666aaa6c98f4c010011c12e6f612a585d5f4c4.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b79d4f2666aaa6c98f4c010011c12e6f612a585d5f4c4.jpg?mw=700" alt="Vercel 側が反応" /></a></p>
<p>すると、 Vercel 側でプロジェクトが反応してビルドが走り始めました。</p>
<p><a href="https://crieit.now.sh/upload_images/75c7890bf380c4b476fea57535096623612a586141166.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/75c7890bf380c4b476fea57535096623612a586141166.jpg?mw=700" alt="デプロイ完了" /></a></p>
<p>microCMS に記事を追加すると、 Github のリポジトリに push することなく勝手にビルドが走ってサイトが更新されることが確認できました。</p>
<p>これで Gatsby.js + Vercel + microCMS で JAMStack なブログの仕組みが構築できました。実験成功です。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<h3 id="改修"><a href="#%E6%94%B9%E4%BF%AE">改修</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/k1_style/scraps/07cce0dd3611e3">Gatsby + microcms + Vercel でブログを作って公開したい</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.gatsbyjs.com/plugins/gatsby-source-microcms/">gatsby-source-microcms | Gatsby</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/rokki188/articles/948d53199508c7">microCMS + Next.js でJamStackブログを作ってみた</a></li>
</ul>
<h3 id="コード、GraphQL、microCMSの設定、環境変数"><a href="#%E3%82%B3%E3%83%BC%E3%83%89%E3%80%81GraphQL%E3%80%81microCMS%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%80%81%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0">コード、GraphQL、microCMSの設定、環境変数</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.microcms.io/microcms-next-jamstack-blog/">microCMS + Next.jsでJamstackブログを作ってみよう | microCMSブログ</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.microcms.io/gatsby-microcms-media/">GatsbyJS + microCMSでJamstackなオウンドメディアを作ろう | microCMSブログ</a></li>
</ul>
<h3 id="Vercel の環境変数"><a href="#Vercel+%E3%81%AE%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0">Vercel の環境変数</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://vercel.com/docs/environment-variables">Vercel – Environment Variables - Vercel Documentation</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.snorerelax.com/posts/tech-vercel-environment/">Vercelで環境変数を設定する | Next.js Blog Example with すのりら</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/Slowhand0309/items/f954237520d343fa9e4c">Vercelで設定した環境変数をNext.jsで使用する - Qiita</a></li>
</ul>
<h4 id="環境変数の分かち書き"><a href="#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AE%E5%88%86%E3%81%8B%E3%81%A1%E6%9B%B8%E3%81%8D">環境変数の分かち書き</a></h4>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.gaji.jp/2020/06/09/4030/">GatsbyJSで開発環境にのみページを存在させる方法 ++ Gaji-Laboブログ</a></li>
</ul>
<h3 id="gatsby-plugin-feed"><a href="#gatsby-plugin-feed">gatsby-plugin-feed</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.gatsbyjs.com/plugins/gatsby-plugin-feed/">gatsby-plugin-feed | Gatsby</a></li>
</ul>
<p>基本 Gatsby.js のプラグインのページはシンプルなサンプルなので <code>http://localhost:8000/___graphql</code> で GraphQL を試して感覚をつかむ方が早かった気がします。</p>
arm-band
tag:crieit.net,2005:PublicArticle/17622
2021-08-29T00:35:00+09:00
2021-08-29T00:35:39+09:00
https://crieit.net/posts/gatsby-vercel-microcms-cooprate-20210829-1
microCMS にアカウントを登録して記事を作成するまで
<p><a href="https://crieit.net/posts/publish-blog-by-gatsvyjs-vercel-20210825">Gatsby.js + Vercel の試験</a>の続きとして、記事を Markdown ファイルから microCMS に移管するために準備します。</p>
<h2 id="アカウント作成"><a href="#%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E4%BD%9C%E6%88%90">アカウント作成</a></h2>
<p>まずは <a target="_blank" rel="nofollow noopener" href="https://microcms.io">microCMS</a> にアカウントを作成します。</p>
<p><a href="https://crieit.now.sh/upload_images/b3d6456213b23f2099ed1416d7fca5ca612a55bdc21a1.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b3d6456213b23f2099ed1416d7fca5ca612a55bdc21a1.jpg?mw=700" alt="microCMS トップページ" /></a></p>
<p>「無料で始める」をクリック。</p>
<p><a href="https://crieit.now.sh/upload_images/6d3183b223be0499d403da64df5fa30a612a55cb5a96e.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6d3183b223be0499d403da64df5fa30a612a55cb5a96e.jpg?mw=700" alt="アカウント登録" /></a></p>
<p>メールアドレスとパスワードを設定。</p>
<p><a href="https://crieit.now.sh/upload_images/8ce90d7df2f276c31609e08f09719968612a55ddba483.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8ce90d7df2f276c31609e08f09719968612a55ddba483.jpg?mw=700" alt="ワンタイムピンコード入力" /></a></p>
<p>入力したメールアドレスに届いたワンタイムピンコードを入力。</p>
<p><a href="https://crieit.now.sh/upload_images/7d685f2167382b31f4d9586b85465562612a55e2736a5.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7d685f2167382b31f4d9586b85465562612a55e2736a5.jpg?mw=700" alt="登録完了" /></a></p>
<p>登録完了。</p>
<p><a href="https://crieit.now.sh/upload_images/0c24dd37397c5d52fe2cb6c0fa17bb89612a55e52c57f.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/0c24dd37397c5d52fe2cb6c0fa17bb89612a55e52c57f.jpg?mw=700" alt="チュートリアルの続き" /></a></p>
<p>登録完了からチュートリアルの続き。まずはサービス名とサービスIDを入力。これはAPIとは別なのでもう少し抽象的というか上のレイヤーの名前にしておきます。</p>
<p>ちなみにサービスIDは後でパラメータとして使用するので控えておきます。</p>
<p><a href="https://crieit.now.sh/upload_images/ab47849773a8ddccd7e121732b123c14612a55ebee426.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ab47849773a8ddccd7e121732b123c14612a55ebee426.jpg?mw=700" alt="プラン設定" /></a></p>
<p>プランは Hobby にしておきます。</p>
<p><a href="https://crieit.now.sh/upload_images/ecea90965e92ac27ad70b60375b01898612a55f0bb1e9.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ecea90965e92ac27ad70b60375b01898612a55f0bb1e9.jpg?mw=700" alt="サービス登録完了" /></a></p>
<p>サービス登録完了。</p>
<h2 id="スキーマ定義"><a href="#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E5%AE%9A%E7%BE%A9">スキーマ定義</a></h2>
<p>続いて API の中身を。</p>
<p><a href="https://crieit.now.sh/upload_images/7f11550e964f5ee323d8013d6ed65544612a55f7a6f93.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7f11550e964f5ee323d8013d6ed65544612a55f7a6f93.jpg?mw=700" alt="API名とエンドポイント" /></a></p>
<p>API名とエンドポイントを設定。エンドポイントはサービスID同様後でパラメータとして使用するので控えておきます。</p>
<p><a href="https://crieit.now.sh/upload_images/dd64a9785b2e38919a34e4874cc50c31612a55fa406a6.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/dd64a9785b2e38919a34e4874cc50c31612a55fa406a6.jpg?mw=700" alt="形式選択" /></a></p>
<p>レスポンスの形式を設定します。配列かオブジェクトの二択のようです。ここでは配列にしておきます。</p>
<p><a href="https://crieit.now.sh/upload_images/e118db36206380369012ed39b3032ec2612a5602893c4.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/e118db36206380369012ed39b3032ec2612a5602893c4.jpg?mw=700" alt="スキーマ登録" /></a></p>
<p>続いてスキーマの設定。</p>
<p><a href="https://crieit.now.sh/upload_images/dd2a5e43d92a5845e8aee4499e065842612a560524292.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/dd2a5e43d92a5845e8aee4499e065842612a560524292.jpg?mw=700" alt="スキーマ一覧" /></a></p>
<p>色々調整して最終的にこんな感じになりました。</p>
<h2 id="記事作成"><a href="#%E8%A8%98%E4%BA%8B%E4%BD%9C%E6%88%90">記事作成</a></h2>
<p>先のスキーマに則って記事を作成します。</p>
<p><a href="https://crieit.now.sh/upload_images/1f466017d9448f07d2c561116ec0bd63612a560e10480.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1f466017d9448f07d2c561116ec0bd63612a560e10480.jpg?mw=700" alt="記事サンプル" /></a></p>
<p>記事サンプル。</p>
<p><a href="https://crieit.now.sh/upload_images/0121070f7774f995df08c9f5dea841f7612a5610811d0.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/0121070f7774f995df08c9f5dea841f7612a5610811d0.jpg?mw=700" alt="記事一覧" /></a></p>
<p>試しに記事をいくつか作成。</p>
<p>ひとまず、 microCMS の操作も分かってきました。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/k1_style/scraps/07cce0dd3611e3">Gatsby + microcms + Vercel でブログを作って公開したい</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.microcms.io/microcms-next-jamstack-blog/">microCMS + Next.jsでJamstackブログを作ってみよう | microCMSブログ</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://blog.microcms.io/gatsby-microcms-media/">GatsbyJS + microCMSでJamstackなオウンドメディアを作ろう | microCMSブログ</a></li>
</ul>
arm-band