s

GatsbyJSで作成したサイトに後からNetlify CMSを導入する方法

静的ジェネレータでサイトを作って維持していくと、その内、中身のコンテンツの管理が問題になると思います。
コンテンツ管理問題を解決するためにはCMSの導入という手段があります。
GatsbyJSの場合、startarで簡単に導入できるNetlify CMSが有名です。
ただ、Web検索しても出てくるのは、startarを使って導入する方法ばかり……。
そうじゃないんだよ! 私が知りたいのはサイトを作った後からNetlify CMSを導入する方法なんだ!
ということで、今回は実際に、startarを使わずにGatsbyJSにNetlify CMSを導入したので、その方法を解説していきます。

Netlifyの認証機能を有効にする

実際にNetlify CMSの設定に必要なファイルを作っていく前に、Netlify側で認証機能を有効にしましょう。
config.ymlの作成方法backendの指定のところを参考にしてください。
Netlifyにログインします。

Git Gatewayを有効にする

NetlifyのSettings > Identity > Git Gatewayで、Enable Git Gatewayをクリック。
NetlifyでGit Gatewayの有効化
gatsbyjs_netlifycms_01

招待した人しかログイン出来ないようにする

Registration SettingsのEdit settingsから、Invite onlyを選択しましょう。
招待した人しか管理画面にログインできないようにする
gatsbyjs netlifycms 02
Netlify Identity widgetを埋め込みます。
Netlifyで、認証制にしたいサイトを選択 > Settings > Build & Deploy >Snippet InjectionからAdd Snippet
下記コードを
</head>
の前に挿入します。
1<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
2
headタグ内にNetlify Identity Widgetのスニペットを追加する
gatsbyjs netlifycms 03

CMSにログインするユーザーを招待する

Netlifyで、認証制にしたいサイトを選択 > IdentityからInvite users
招待したいユーザーのメールアドレスを入力してSend
メールが届くので、Accept the Inviteをクリック
届いたメールから招待を受ける
gatsbyjs netlifycms 04
パスワードを入力してSign Up
パスワードを入力してSign Up
gatsbyjs netlifycms 05
ログインできました!
Netlifyログイン完了
gatsbyjs netlifycms 06
次は、Netlify CMSの設定に必要なファイルを作っていきましょう。

/static の下に設定ファイルを作成する

GatsbyJSの場合は、/staticフォルダの下に、Netlify CMS設定用のファイルを追加します。
1/static
2 └ admin
3   ├ index.html
4   └ config.yml
5
/staticフォルダの下にadminフォルダ、その下にindex.htmlconfig.ymlを作成します。
ファイル名説明
index.html管理ページを表示するのに必要なファイル
config.yml管理ページ内の設定をするのに必要なファイル

index.htmlの作成方法

index.htmlは公式サイト記載の内容をコピーして作ります。
1<!doctype html>
2<html>
3<head>
4  <meta charset="utf-8" />
5  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6  <title>Content Manager</title>
7</head>
8<body>
9  <!-- Include the script that builds the page and powers Netlify CMS -->
10  <script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
11</body>
12</html>
13

config.ymlの作成方法

npmモジュールのインストール

config.ymlを作成する前に、GatsbyJSのリポジトリにNetlify CMSのnpmモジュールをインストールします。
1npm install netlify-cms --save-dev
2
もしくは
1yarn add netlify-cms --dev
2
このサイトの場合、config.ymlの中身はこんな感じになっています。
1backend:
2  name: git-gateway
3publish_mode: editorial_workflow
4media_folder: 'content/post/img/upload'
5public_folder: '/img/upload'
6locale: 'ja'
7collections:
8  - name: 'post'
9    label: 'Post'
10    folder: 'content/post'
11    create: true
12    extension: 'md'
13    slug: '{{fields.slug}}'
14    fields:
15      - { label: 'Slug', name: 'slug', widget: 'string' }
16      - { label: 'Title', name: 'title', widget: 'string' }
17      - {
18          label: 'Date',
19          name: 'date',
20          widget: 'datetime',
21          format: 'YYYY-MM-DD HH:mm',
22        }
23      - {
24          label: 'Update',
25          name: 'update',
26          default: '',
27          widget: 'datetime',
28          format: 'YYYY-MM-DD HH:mm',
29          required: false,
30        }
31      - {
32          label: 'Description',
33          name: 'description',
34          widget: 'text',
35          required: false,
36        }
37      - {
38          label: 'Category',
39          name: 'category',
40          widget: 'relation',
41          collection: 'categorylist',
42          searchFields: ['name'],
43          valueField: 'name',
44        }
45      - {
46          label: 'Tags',
47          name: 'tags',
48          widget: 'list',
49          allow_add: true,
50          minimize_collapsed: true,
51          summary: '{{fields.tag}}',
52          field: { label: Tag, name: tag, widget: 'string' },
53        }
54      - { label: 'Body', name: 'body', widget: 'markdown' }
55  - name: 'page'
56    label: 'Page'
57    folder: 'content/page'
58    create: true
59    extension: 'md'
60    slug: '{{fields.slug}}'
61    fields:
62      - { label: 'Slug', name: 'slug', widget: 'string' }
63      - { label: 'Title', name: 'title', widget: 'string' }
64      - {
65          label: 'Date',
66          name: 'date',
67          widget: 'datetime',
68          format: 'YYYY-MM-DD HH:mm',
69        }
70      - {
71          label: 'Update',
72          name: 'update',
73          default: '',
74          widget: 'datetime',
75          format: 'YYYY-MM-DD HH:mm',
76          required: false,
77        }
78      - {
79          label: 'Description',
80          name: 'description',
81          widget: 'text',
82          required: false,
83        }
84      - { label: 'Body', name: 'body', widget: 'markdown' }
85  - name: 'categorylist'
86    label: 'Category'
87    identifier_field: name
88    create: true
89    extension: 'yml'
90    folder: 'content/category'
91    fields:
92      - { label: 'Name', name: 'name', widget: 'string' }
93      - { label: 'Description', name: 'description', widget: 'text', required: false}
94
順を追って説明していきます。

backendの指定

1backend:
2  name: git-gateway
3
backendを指定します。
指定方法によって、認証の仕方が変わってきます。
Netlify Identity widgetを使用する場合は、
name:git-gateway
を指定します。
GitHubでログインできれば良い場合は、下記のように指定します。
1backend:
2name: github
3repo: ユーザー名/レポジトリ名
4

publish modeの指定(editorial_workflow)

1publish_mode: editorial_workflow
2
下書きを有効にするかの指定です。
editorial_workflowを指定すると、下の画像のように、かんばん方式で記事の状態を管理できます。
記事を公開できる状態になったら「準備完了」へステータスを移して公開しましょう。
Netlify CMSのワークフロー画面 下書きの管理を行う
gatsbyjs netlifycms 07

画像フォルダの指定

1media_folder: 'content/post/img/upload'
2public_folder: '/img/upload'
3
画像フォルダの指定は、
media_folder
public_folder
で行います。
  • media_folder:実際に画像を保管するフォルダを指定(プロジェクトのルートフォルダからの相対パス)
  • public_folder:記事中で画像を取得するときの相対パス

collectionの指定(コンテンツ管理の単位)

collectionで、コンテンツ管理の単位を指定します。
記事やページを分けて管理したい場合や、カテゴリー一覧を管理する場合に使えます。
1collections:
2  - name: 'post'
3    label: 'Post'
4    folder: 'content/post'
5    create: true
6    extension: 'md'
7    slug: '{{fields.slug}}'
8    fields:
9      - { label: 'Slug', name: 'slug', widget: 'string' }
10      - { label: 'Title', name: 'title', widget: 'string' }
11      - {
12          label: 'Date',
13          name: 'date',
14          widget: 'datetime',
15          format: 'YYYY-MM-DD HH:mm',
16        }
17      - {
18          label: 'Update',
19          name: 'update',
20          default: '',
21          widget: 'datetime',
22          format: 'YYYY-MM-DD HH:mm',
23          required: false,
24        }
25      - {
26          label: 'Description',
27          name: 'description',
28          widget: 'text',
29          required: false,
30        }
31      - {
32          label: 'Category',
33          name: 'category',
34          widget: 'relation',
35          collection: 'categorylist',
36          searchFields: 'name',
37          valueField: 'name',
38        }
39      - {
40          label: 'Tags',
41          name: 'tags',
42          widget: 'list',
43          allow_add: true,
44          minimize_collapsed: true,
45          summary: '{{fields.tag}}',
46          field: { label: Tag, name: tag, widget: 'string' },
47        }
48      - { label: 'Body', name: 'body', widget: 'markdown' }
49
それぞれの項目の詳細は下記の通り。
項目説明
namecollectionの名前。他のcollectionからrelationで紐付けるときにも使う
label管理画面に表示する名前
foldercollectionのファイルを格納するフォルダを指定。例えば、postのfolderを
content/post
で指定すると、content/postフォルダの中身をpostとして扱う
create
true
にすると、管理画面上で新しいファイルが作成できる
extensionファイルの保存形式。
yaml
toml
json
md
markdown
html
が指定できる
slugファイル名の指定
fieldscollectionの各ファイル編集ページに持たせるフィールド。詳しくは後述

fieldsの指定

fields部分を抜き出すとこんな感じになっています。
1    fields:
2      - { label: 'Slug', name: 'slug', widget: 'string' }
3      - { label: 'Title', name: 'title', widget: 'string' }
4      - {
5          label: 'Date',
6          name: 'date',
7          widget: 'datetime',
8          format: 'YYYY-MM-DD HH:mm',
9        }
10      - {
11          label: 'Update',
12          name: 'update',
13          default: '',
14          widget: 'datetime',
15          format: 'YYYY-MM-DD HH:mm',
16          required: false,
17        }
18      - {
19          label: 'Description',
20          name: 'description',
21          widget: 'text',
22          required: false,
23        }
24      - {
25          label: 'Category',
26          name: 'category',
27          widget: 'relation',
28          collection: 'categorylist',
29          searchFields: 'name',
30          valueField: 'name',
31        }
32      - {
33          label: 'Tags',
34          name: 'tags',
35          widget: 'list',
36          allow_add: true,
37          minimize_collapsed: true,
38          summary: '{{fields.tag}}',
39          field: { label: Tag, name: tag, widget: 'string' },
40        }
41      - { label: 'Body', name: 'body', widget: 'markdown' }
42
基本的な項目は下記のとおりです。
項目説明
label管理画面上に表示するフィールド名
nameフィールドの値を判別する名前。GraphQLで指定するfieldsと合わせる
widgetフィールドの種類を指定する
required
false
を指定すると、入力を任意にできる。
widgetによって、何を指定しなければいけないかが変わります。
詳しくはWidgets | Netlify CMS | Open-Source Content Management Systemを参照してください。
投稿のマークダウン部分を取得するには、下記の通り指定します。
1- { label: 'Body', name: 'body', widget: 'markdown' }
2
この指定をすると、今までの投稿内容も取得されます。

作成できたら開発環境で確認しよう

ファイルが作成できたら、開発環境で確認します。
adminフォルダ内のindex.htmlがサイトURL/adminになるので、
develop
ではなく、
build
serve
を使います。
1gatsby build
2
してから、
1gatsby serve -H 0.0.0.0
2
してください。
-H
以降はPC以外でローカルホストを表示させるためのオプションなので、なくても大丈夫です。
**http://localhost:9000/admin**を開いて反映されていることを確認しましょう。

pushして反映させる

開発環境でうまく表示ができていたら、ローカルリポジトリにpushして反映させます。
buildが完了したら、サイトURL/adminにアクセスして管理画面を確認しましょう。
  • 2020年6月13日
  • 2020年6月21日

記事を共有する

執筆者

sake

現役システムエンジニア。 普段はホスト系のお仕事してます。

ブログでは主にWeb関係の技術について、勉強したことや実際にコーディングしてみた内容を発信していきます。

トップへ戻る