Gatsby＋microCMSで手を打つ

# Gatsby＋microCMSで手を打つ

### Intro
Angular…、そしてNext.js…。
SPAを開発しているのにSSRを考えないとイカン…なことが多くAngularから流れてくる人多いと思う。そんなこともあってNext.jsを始めたがページリロードすると404エラーとか…、それを解決するのにFunctionをとか導入して関数を書いてサーバー側で…とかもういいかげんにしてと思ってきた。
Nuxtにするか、とまた本買ってしまったが調べてみるとこれでもどうも同じことになるようで無駄な出費またまたあーもーとかなってるところにGatsbyって来て、情報が少ないものの「URLを直叩きしようがリロードしようが、404エラーが帰ってくることはなくなります」（[Reactの最強フレームワークGatsby.jsの良さを伝えたい！！](https://qiita.com/hppRC/items/00739eaf9ae7fc95c1ca)）
ということなので賭けてみる。

### Gatsbyプロジェクト作成
1. node インストール
2. git インストール
3. gatsby-cli インストール<br>
`npm install --global gatsby-cli`
4. プロジェクト作成<br>
`gatsby new <プロジェクト名>`
（gatsby-default-starterがあたる）
5. プロジェクトフォルダに移動してローカル環境立ち上げ<br>`gatsby develop`
6. http://localhost:8000 にアクセス<br>
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/bf8e99fd-68b8-29c6-52c8-d4fe11aa4571.png)

フォルダ構造をみてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/3ff7f578-370b-39a4-856e-94d07abea640.png)
とってもNextと似ているのでつい最近の苦労は無駄でなかったと救われる。
`gatsby-config.js`というファイルがプラグイン管理
その他のgatsby-ほにゃらら.jsファイルはデフォルトでカラ。

package.jsonを見てみる

```json
{
  "name": "gatsby-starter-default",
  "private": true,
  "description": "A simple starter to get up and developing quickly with Gatsby",
  "version": "0.1.0",
  "author": "Kyle Mathews <mathews.kyle@gmail.com>",
  "dependencies": {
    "gatsby": "^2.20.12",
    "gatsby-image": "^2.3.1",
    "gatsby-plugin-manifest": "^2.3.3",
    "gatsby-plugin-offline": "^3.1.2",
    "gatsby-plugin-react-helmet": "^3.2.2",
    "gatsby-plugin-sharp": "^2.5.3",
    "gatsby-source-filesystem": "^2.2.2",
    "gatsby-transformer-sharp": "^2.4.3",
    "prop-types": "^15.7.2",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-helmet": "^6.0.0"
  },
  "devDependencies": {
    "prettier": "2.0.4"
  },
・・・以下略・・・
```

reactから派生したんだなとわかる。

### microCMSとの連携

ヘッドレスCMSはmicroCMSが評判が良いようなのでこれで。

1. microCMS用のプラグインをインストールする。

```bash
$ yarn add gatsby-source-microcms
```
2. つぎに `gatsby-config.js`を編集する

```jsx
・・・前略・・・
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
      },
    },
// 追加↓
    {
      resolve: "gatsby-source-microcms",
      options: {
        apiKey: "X-API-KEY",
        serviceId: "guitar-club",
        endpoint: "news",
      },
    },
// 追加↑
  ],
}
```

micorCMSのAPI-KEY, サービスID、エンドポイントをoptions:{...}に書けばよいようである。書かないで`gatsby develop`してもエラーでたち上がらない。

なのでmicroCMSの設定を。

### microCMS準備

microCMSのサイトはこちら→ https://microcms.io/ 
ここでアカウント作成してログイン。
ここでは医療系情報サイトをイメージして、一般情報、患者さん向け、医師向け、といったカテゴリーがあり、それぞれのカテゴリーに多くの情報ページがぶらさがる単純な2階層のWebサイトをイメージして作ってみる。

まずはサービス名とサービスIDを入力。サービスIDはエンドポイントのサブドメインになる（※ https://＜サービス名＞.microcms.io/ となる）。自分のプロジェクト名とかサイト名がいいだろうわかりやすいし。たとえばhogehoge.jpというサイトだったらhogehogeとか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/ed690260-838a-7505-ca06-cf35ece1c84d.png)




次にコンテンツを作成する。まずはカテゴリーというAPIを作る。左端メニューの「コンテンツ　✙」の✙をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/a323397f-d5e1-7fb1-d56b-9fea5a9caea4.png)

カテゴリー、categoryと入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/e18076d7-d863-78a2-c368-6e30508bb07b.png)


リスト形式をえらぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/f930e89a-453a-f42b-0e9b-b395094e036f.png)

スキーマをつくる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/7530f6dd-2763-3dc8-9cd7-7cec15ee4ff5.png)

追加する、をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/612faa9c-39c7-614c-edc0-d2166a33fca9.png)

患者向けカテゴリーとしてpatientsと入力した。公開ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/b0f7ff7c-ef20-9a04-1e36-7dba619ffd9b.png)

ほかのカテゴリーも同様に追加していく。ここでは医師向けとしてdoctors、一般情報としてbasicsと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/bf927e27-d791-d775-d6fd-7137b9beb6e0.png)

次にカテゴリーの下にぶらさげるコンテンツを作っていく。
またコンテンツ✙をクリックして、記事コンテンツ、articlesと入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/c343caad-c1b8-ee48-dffb-23c02757a0c6.png)

リスト形式を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/cfb29c44-58c9-339f-4173-49261a95e06b.png)

スキーマをつくっていく。このように。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/baffceaf-c30b-5b78-be9d-92ef9ce95918.png)


種類とあるが、だいたい良く知ったようなものだ。テキストフィールドとかテキストエリアとか。ブログみたくリッチに編集したかったらリッチエディタで画像やリンクを張ったりもできる。カラーピッカーはまだないようだが・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/9441c9ed-9c33-d565-ef38-4f161128c53c.png)


最後にカテゴリーフィールドをつくる。種類は「複数コンテンツ参照」というのを選び、さっき作った「カテゴリー」APIを選んで決定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/24eabaa8-e258-35c1-67e8-55c461d3892e.png)

作成できたら、APIリファレンスをクリックしてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/14ca804d-139d-5a46-6862-30fe36ce0f2b.png)

GET /articles/{CONTENT_ID}とあるが、つまりエンドポイントは`https://＜サービスID＞.microcms.io/api/v1/articles/`になる。gatsbyの場合、`gatsby-config.js`のendpoint：に"articles"とだけ書けばいいが、Next.jsなどではgetInitialProps()で

```javascript
const res = await axios.get(`https://＜サービスID＞.microcms.io/api/v1/articles/`,
key
)
```
のようにしなければならないようである。参考：[Next.js + microCMS + NetlifyでJAMstackな世界に入門する](https://qiita.com/kamimura3589/items/07bd5fc2a93105dfe180#%E4%BB%8A%E5%9B%9E%E4%BD%9C%E3%82%8Bjamstack%E3%81%AA%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AE%E5%85%A8%E4%BD%93%E5%83%8F)

APIキーもここに載ってる。表示ボタンをクリックして表示させてコピーして使う。
<br>
次にAPI設定をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/fed2e1c3-dd74-6640-b417-9845f70037e3.png)

ここでさっき作ったフィールドを削除、追加、編集できる。なので最初は適当にタイトルとか内容（コンテンツ）とかとかまあ適当に・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/c20f0718-485d-3cd0-3dee-d2039c49dc53.png)


あとはブログみたく中身をいれるだけ。入力したら公開をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/15c7de56-fc94-3afd-d09c-aff010254960.png)


「カテゴリー」フィールドは患者さん向けのpatientsにした（入力するときpatients, doctors, basicsから選ぶ）。「紹介アイコン」フィールドは種類を「画像」にしたpictというフィールドである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/8ccf7c2c-5a59-9433-fc55-74e84aeee85a.png)



このようにして、カテゴリーpatientsの記事を２つ作ってみた。
患者さん向け記事①
患者さん向け記事②
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/63099518-24e6-409f-5ccb-8f48ee622de1.png)

###ではコーディング
####各記事紹介ページを作成

まずは`gatsby-config.js`にAPI、サービスID、エンドポイントを設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/5c520787-bb60-1e1d-6c96-8862388958fa.png)


pagesの下にpatients.jsを作成、以下のようにコード。

```jsx
// pages/patient.js
import React from "react"
import { graphql　} from "gatsby"

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


const PatientsPage = ({ data }) => (
 <Layout>
   <SEO title="患者の方へ" />

   {data.allMicrocmsArticles.edges.map(edge => {
     const articles = edge.node
     const category = edge.node.category[0].name
     console.log('◆categoryは　' + category)

     if (category == 'patients') {      //カテゴリーが患者さん用の場合表示
       return (
        <React.Fragment key={articles.id}>
         <div>
             <h2>{articles.title}</h2>
             <p>{articles.feature}</p>
           <img
             src={articles.pict.url}
             width={110}
             height={110}
             alt="pict画像"
           />
         </div>
         <div>
             {articles.category.map(category => (
               <React.Fragment key={category.id}>
                 <span>カテゴリー：{category.name}</span>
               </React.Fragment>
             ))}
        </div>
        <hr />
       </React.Fragment>
       )
     } else { return }
   })}
 </Layout>
)

export const query = graphql`
 {
    allMicrocmsArticles(
     sort: { fields: [createdAt], order: DESC }
   ) {
     edges {
       node {
         id
         title
         title_origin
         category {
           id
           name
         }
         pict {
           url
         }
         body
         feature
       }
     }
   }
 }
`

export default PatientsPage
```

そして
`gatsby develop`で立ち上げて`https://localhost:8000/patients`にアクセスする。ふたつの記事のタイトルと紹介文と紹介画像が降順で表示されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/47bb43bc-a214-6085-648b-4aa52c98480a.png)



GraphQLというのはよくわからんがこんな書き方をするのだなあ、と。

```jsx
// pages/patients.js
・・・略・・・

export const query = graphql`
 {
    allMicrocmsArticles(
     sort: { fields: [createdAt], order: DESC }
   ) {
     edges {
       node {
         id
         title
         title_origin
         category {
           id
           name
         }
         pict {
           url
         }
         body
         feature
       }
     }
   }
 }
`
・・・略・・・
```

`http://localhost:8000/___graphql`にアクセスしてみる。するとGraphQLで受け取ってるデータとデータ構造が見れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/e62ba419-268d-0374-f89a-3e2b2bf93dcf.png)

allMicrocmsArticlesのedgesのnodeに記事のすべてが詰まってる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/281bd3db-01e9-f648-3031-64c73e4ea685.png)

GraphQLでうけとったデータをmapで回してじゅんぐりに表示、ということである。


#### 個別記事の全表示ページを作成

動的なページを作成する際にはデフォではカラだったgatsby-node.jsファイルにコードする（えっ？）。そういうキマリ。

```jsx
// gatsby-node.js
const path = require("path")

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

 const result = await graphql(
   `
     {
        allMicrocmsArticles {
         edges {
           node {
             id
             title
             title_origin
             category {
                id
                name
             }
             body
             feature
             pict {
                 url
             }
           }
         }
       }
     }
   `
 )

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

 result.data.allMicrocmsArticles.edges.forEach(edge => {
     //上記のGraphQLでcategoryを書いてないがnode.categoryを掴めるようだ
     const categoryName = edge.node.category[0].name
     switch (categoryName) {
         case 'patients':  // categoryがpatientsだったらサブパスをpatientsに
             subDir = '/patients/'+ edge.node.id
             break;
         case 'doctors':  // categoryがdoctorsだったらサブパスをdoctorsに
             subDir = '/doctors/'+edge.node.id
             break;
         default:
             subDir = '/articles/'+edge.node.id
     }
   createPage({
     //path: `/patients/${edge.node.id}`,
     path: `${subDir}`,
     component: path.resolve(
       "./src/templates/article.js"
     ),
     context: {
       id: edge.node.id,
     },
   })

 })
}

```

動的なページを作成するためにGatsbyにはcreatePagesというAPIが用意されてて、上のコードで肝になるのはそのcreatePages関数の中だけ。わたしは患者向け記事と医師向け記事と…でサブパスを分けたかったのでSwitch文があるが、単純に以下のようにシンプルでよい。

```jsx
 result.data.allMicrocmsArticles.edges.forEach(edge => {
   createPage({
     path: `/articles/${edge.node.id}`,
     component: path.resolve(
       "./src/templates/article.js"
     ),
     context: {
       id: edge.node.id,
     },
   })

 })
```

`component: path.resolve(
"./src/templates/article.js"
)`
ではテンプレートビューファイルであるarticle.jsを指定してる。次のステップで作成する。
作成先がtemplatesフォルダになるのはそういうキマリかもしくは慣習。

`     context: {
       id: edge.node.id,
     }`
では記事データのIDを指定している。こう書くだけで次のステップで作成するテンプレートに値渡しできるようである。

ではtemplatesフォルダを作成。
そしてその下にarticle.jsファイルを作成（ファイル名は任意）。

```jsx
//templates/article.js
import React from "react"
import { graphql } from "gatsby"

import Layout from "../components/layout"

const ArticlePost = props => {
 const post = props.data.microcmsArticles // ㊟allMicrocmsArticleでない
 return (
   <Layout>
     <div>
       <h2>{post.title}</h2>
       <h3>原文：{post.title_origin}</h3>
       <br />
       <img
         src={post.pict.url}
         width={160}
         height={110}
         alt="pict画像"
       />
       <p
         dangerouslySetInnerHTML={{
           __html: `${post.body}`,
         }}
       ></p>
     </div>
   </Layout>
 )
}

export default ArticlePost

export const query = graphql`
 query($id: String!) {
   microcmsArticles(id: { eq: $id }) {
     title
     title_origin
     body
     pict {
       url
     }
     body
   }
 }
`
```

34行目の`microcmsArticles(id: { eq: $id })`で、gatsby-node.jsのcontextで指定した記事IDが値渡しされている。そしてそのIDをもとにmicrocmsArticlesからデータをGraphQLで引っ張っている。個別の記事をとってきたいのでallMicrocmsArticleではないところ、注意。

<br>
さいごにpatients.jsにリンクをはる。

```js

// pages/patients.js
・・・略・・・
        <React.Fragment key={articles.id}>
         <div>
             <Link to={`/patients/${articles.id}`}>
                <h2>{articles.title}</h2>
             </Link>
             <p>{articles.feature}</p>
・・・略・・・
```


これでgatsby developでビルドしなおすと（gatsby-node.jsファイルのコードを変更すると、変更内容にもよるがビルドしなおさないといけないみたい）詳細ページが表示されるようになる。

患者向け②をクリックしてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/6a8a3e6d-60ff-9174-a47f-16167c0a4de0.png)


表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/9d0bf9aa-17f7-8f82-2af4-d589ad4f2a10.png)

URLはコレ

http://localhost:8000/patients/a9cd9e19-8a1f-5ad9-b753-00bc8dbfa875

titleをURLにしたかったらedge.node.titleにすれば以下のようになるだろう。日本語がイヤだったら記事コンテンツAPIに英語タイトルなりのフィールドを追加するだけだ(半角スペースはいれないよう）
http://localhost:8000/patients/患者さん用記事②


リロードしても４０４エラーにならない。すばらしい。

<br>
### 補足
医師向け記事も同じようにしてふたつ作った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/3c5211a3-8f00-d40c-f582-f06a281fd8df.png)

pagesフォルダの下にdoctors.jsファイルを作成、patients.jsのコードをコピペして少し編集しただけ。microCMS側では記事を作成時、カテゴリーをdoctorsにするだけだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/82b43086-548d-c8ac-3c1e-b21e137d144a.png)

もちろん、`gatsby-node.js`と`templates/article.js`はなにも変更する必要ない。


```jsx
// pages/doctors.js
import React from "react"
import { graphql, Link　} from "gatsby"

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


const PatientsPage = ({ data }) => (
 <Layout>
   <SEO title="医師の方へ" />

   {data.allMicrocmsArticles.edges.map(edge => {
     const articles = edge.node
     const category = edge.node.category[0].name
     
     console.log('◆categoryは　' + category)
     console.log('◆articles.idは　' + articles.id)
     console.log('◆リンク先は　' + `/doctors/${articles.id}`)

     if (category === 'doctors') {      //カテゴリーが医師用の場合表示
       return (
        <React.Fragment key={articles.id}>
         <div>
             <Link to={`/doctors/${articles.id}`}>
                <h2>{articles.title}</h2>
             </Link>
             <p>{articles.feature}</p>
           <img
             src={articles.pict.url}
             width={110}
             height={110}
             alt="pict画像"
           />
         </div>
         <div>
         {articles.category.map(category => (
               <React.Fragment key={category.id}>
                 <span>カテゴリー：{category.name}</span>
               </React.Fragment>
         ))}
        </div>
        <hr />
       </React.Fragment>
       )
     }
   })}
 </Layout>
)

export const query = graphql`
 {
    allMicrocmsArticles(
     sort: { fields: [createdAt], order: DESC }
   ) {
     edges {
       node {
         id
         title
         title_origin
         category {
           id
           name
         }
         pict {
           url
         }
         body
         feature
       }
     }
   }
 }
`

export default PatientsPage
```

### 補足２
React Bootstrapとの相性もすばらしい（Reactだからアタリマエか）。参考：[GatsbyにReact bootstrap導入とナビゲーションバー](https://qiita.com/atomyah/items/5eb8b0019665254876da)


### 補足３
GraphQLも扱いが簡素で良い。[JSONデータを読んでくる](https://qiita.com/atomyah/items/0f2bf570d1dc008d1ba8)てのをやったがスムーズ、簡単。RESTより確かにいいかもしれない。Queryしか試してないけど…。
参考：
[10分で GraphQL 入門](https://qiita.com/yuku_t/items/331e366dc20ae9900448)
[GraphQL解説 (AWS AppSync)](https://www.slideshare.net/AmazonWebServicesJapan/graphql-aws-appsync)

### ギャツビー最高
確かにこれでイケるかもしれない。
海外では静的サイトジェネレータならGatsbyって流れになってるようだけど、日本で知名度がイマイチな理由は資生堂ギャツビーと同じ名前が微妙だからではないだろうか？

<br />

# 本の宣伝
### Gatsbyバージョン５>>>>改訂２版

**前編**の『Gatsby５前編ー最新Gatsbyでつくるコーポレートサイト』と**後編**の『Gatsby５後編ー最新GatsbyとmicroCMSでつくるコーポレートサイト《サイト内検索機能付き》』を合わせ、次のようなデモサイトを構築します。
→ **https://yah-space.work**
<hr />


静的サイトジェネレーターGatsby**最新バージョン５**の基本とFile System Route APIを使用して動的にページを生成する方法を解説。またバージョン５の新機能《**Slicy API**》《**Script API**》《**Head API**》を紹介、実装方法も。《**Gatsby Functions**》での問い合わせフォーム実装やGatsby Cloudへのアップロード方法も！


<a href="https://www.amazon.co.jp/gp/product/B0BXNJTJMY?&linkCode=li3&tag=kokkahasan-22&linkId=93c5e3bf1f226141ddc807300e81b07a&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B0BXNJTJMY&Format=_SL250_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=kokkahasan-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=kokkahasan-22&language=ja_JP&l=li3&o=9&a=B0BXNJTJMY" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<a target="_blank" href="https://www.amazon.co.jp/gp/product/B0BXXBDJDJ?&linkCode=ll1&tag=kokkahasan-22&linkId=df7e600968c58c0090cd735681c6732c&language=ja_JP&ref_=as_li_ss_tl">Gatsby５前編ー最新Gatsbyでつくるコーポレートサイト ～基礎の基礎から応用、新機能の導入まで（書籍2,980円）</a>

<br />
<br />

**最新Gatsby５**とmicroCMSを組み合わせてのコーポレートサイト作成手順を解説。《**サイト内検索機能**》をGatsbyバージョン４からの新機能《**Gatsby Functions**》と《**microCMSのqパラメータ**》で実装。また、**SEOコンポーネントをカスタマイズ**して**microCMS APIをツイッターカードに表示**させる**OGPタグ**実装方法も解説。

<a href="https://www.amazon.co.jp/gp/product/B0BXN99WSV?&linkCode=li3&tag=kokkahasan-22&linkId=68f1905bf915f6bd365559a0c65bcdd1&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B0BXN99WSV&Format=_SL250_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=kokkahasan-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=kokkahasan-22&language=ja_JP&l=li3&o=9&a=B0BXN99WSV" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<a target="_blank" href="https://www.amazon.co.jp/dp/B0BXN99WSV?_encoding=UTF8&qid=&sr=&linkCode=li2&tag=kokkahasan-22&linkId=f02e2f9c50736e3f074b38b4cd73894a&language=ja_JP&ref_=as_li_ss_il">Gatsby５後編ー最新GatsbyとmicroCMSでつくるコーポレートサイト《サイト内検索機能付き》（書籍 2,790円）</a>

<br />