Gatsby + Netlify CMSで作ったブログをカスタマイズする

かれこれ、WordPress→Tumblr→はてなブログという感じで色んなブログサービスを転々としてきましたが、最近になってGatsby + Netlifyという単語をよく聞くようになったので試してみました。

Gatsby

https://www.gatsbyjs.org/

React製の静的サイトジェネレータです。

Gatsbyで生成されたサイトはSPA(Single Page Application)でかつPWA(Progressive Web Apps)なのでだいぶ高速です。

Markdownのファイルでブログを書けるのも便利。

通常、生成されたサイトはGitHub PagesやAmazon S3等に置くと思うのですが、そこに新しく登場したのがNetlifyです。

Netlify

https://www.netlify.com/

フロントエンドのビルド・デプロイ・ホスティングをまるっとやってくれるサービスです。

GitHub Pagesを使えばええやんって最初は思いましたが、SPAのビルド後のファイルは大きいのでGitHub上に置きたくないですよね。

何らかのCIツールと組み合わせてAmazon S3あたりにデプロイするのはアリです。

Netlifyではそのあたりの処理を全部やってくれて、かつ以下のような特徴があります。

  • 無料でHTTPS対応
  • カスタムドメインOK
  • キャッシュ無効化
  • 制限なしのスナップショット、ロールバック
  • Proxyやリダイレクトのルール設定
  • AWS Lambdaを簡単に使える(試してない)

なるほど、良さそうだなと。

けどなんだかんだ言って、ローカルでMarkdownでブログ書くのって意外と画像入れたりするの面倒くさかったりして、結局続かなそうだな〜。

そのあたりのGUIがあれば便利なんだけどな〜と思って念のため探してみたらありました!

Netlify CMS

https://www.netlifycms.org/

文字通り、NetlifyのCMSです。

これは正直言って感動しました。

仕組みとしては、Web上でMarkdownファイルを編集すると自動的にGitHubにPushされ、Netlify側でビルド&デプロイされる感じです。

改めて俯瞰してみると、「それってただの一般的なブログサービスじゃん」とも言えるのですが、ブログのフロントエンド部分が最大限までカスタマイズ可能になっている点がポイントなのかなと思います。

もし自分が一からSPAでブログサービスを作るとしたらそれなりに大変ですが、その大変な部分を全て引き受けてくれて、あとはちょいちょいReactとMarkdown書くだけで良い状態まで持っていってくれるのがNetlify CMSです。(ReactはGatsbyを用いている場合の話)

実践!Gatsby + Netlify CMS

starterkitを使うと恐ろしいほど簡単にサイトを作成できます。

ステップ1

ここにアクセスする。

ステップ2

GitHubと連携する。ボタンをポチッ。

null

ステップ3

サイト用のリポジトリ名を入力する。

null

なんと、これで終わりです。2ポチで完成です。

こんな感じのKALDIコーヒーのサイトがサンプルで出来上がります。

https://friendly-fermat-3994f5.netlify.com/

もちろんサブドメインは自由に変更できます。

また、/adminにアクセスすることで、ログイン後に管理画面に入ることができます。

ソースコードの構成

出来上がったばかりのサイトは以下の4ページで構成されています。

  • Blog
  • About
  • Products
  • Tags

そしてソースコードは以下のような構成になっています。(重要なポイントのみ抜粋)

src/pages

ブログやページのデータソースとなるMarkdownファイルが置かれています。
そしてなぜかブログ一覧ページと404ページのComponentもここにあります。(修正されるかも)

src/templates

主にMarkdownファイルを流し込む先のテンプレートが置かれています。
各ページのカスタマイズをしたい場合はだいたいココをいじることが多いです。

src/layouts

スタイル用のall.sassと大元のテンプレートとなるindex.jsがあります。

最初、CSSは一体どこに書かれているのだろうと探しましたが、all.sass内で読み込んでいるBulmaというCSSテンプレートを使っているようです。

新たにスタイルを書きたい場合はall.sassに付け加えても良いですしStyled-Components等を使うのもアリです。

src/components

ここにはNavbarContentなどのコンポーネントが置かれています。

汎用性を意識したコンポーネントはココに置くのが良さそうです。

src/cms/preview-templates

管理画面におけるサイトやブログのプレビュー画面用のテンプレートです。

BlogPostPreview.jsではsrc/templates/blog-post.jsのコンポーネントを利用しているので、基本的には本番と同じ見え方になるはずです。

static/admin/config.yml

ここだけsrc外ですが、重要なので載せておきます。

管理画面の入力フォームの設定ファイルです。

ここで用意したフォームへの入力をsrc/templates以下でごにょごにょする感じです。

さて、だいたいの構成が分かったのでちょいちょいカスタマイズしてみます。

OGP画像を選択できるようにする

このご時世、OGP対応は必須です。

試しに管理画面の入力フォームにOGP画像選択フォームを追加してみます。

ステップ1

まずはstatic/admin/config.ymlを変更します。

Blogのfieldsに次の一文を追加します。

- {label: "Image", name: "image", widget: "image"}

ここを変更すると、既にブログの記事が存在している場合、それらにImageが設定されていないとビルド時にエラーが出てしまいます。

記事がある場合はsrc/pages/blog以下のMarkdownファイルの先頭部分にImageの設定が必要です。(指定するファイルはとりあえず適当で良いと思います)

こんな感じです。

image: /img/ogp.png

/imgpublic/imgを指します。

ステップ2

src/templates/blog-post.jsを変更します。

ステップ1で修正を行ったことで、post.frontmatter.imageで入力した画像パスを取得することができます。

これをHTMLのHead内のog:imageとして設定してあげれば良いです。

Gatsbyでは内部的にはreact-helmetを用いているので、コンポーネント単位でHTMLヘッダーの上書きを行うことができます。

今回は次のようなHelmetコンポーネントのラッパーを作成し、BlogPostTemplateのhelmetpropsに渡すようにしました。

const Meta = ({ post }) => {
  const origin = 'https://shibe97.com';

  return (
    <Helmet
      title={`${post.frontmatter.title} | Blog`}
      meta={[
        { name: 'description', content: post.frontmatter.description },
        { property: 'og:title', content: post.frontmatter.title },
        { property: 'og:description', content: post.frontmatter.description },
        { property: 'og:image', content: `${origin}${post.frontmatter.image}` },
      ]}
    />
  );
};

ステップ3

ここまででOGP画像は表示できるようになったはずです。

ついでにブログ記事の先頭にもその画像を表示できるようにします。

BlogPostTemplateコンポーネント内の好きな位置にImgタグでpost.frontmatter.imagesを表示させればOKです。

こんな感じで管理画面から設定できるようになります。

null

下書き機能を追加する

Netlify CMSにはデフォルトでは下書き機能が備わっていません。

自作しないといけないかな〜どうやって作ろうかな〜などと考えつつ公式のドキュメントを読んでいたら、あるフラグを切り替えるだけで下書き機能が作れることを知りました。

static/admin/config.ymlに次の一行を追加しましょう。

publish_mode: editorial_workflow

これだけで管理画面に新しくWorkflowというタブが追加されます。

Workflow内はカンバン形式になっており、Drafts / In Review / Readyの3段階に分けて記事を管理することができます。
レビュー機能があるので、複数人での管理にも向いていますね。

null

なぜこんな素晴らしい機能がデフォルトでOFFになっているのか謎です。

まとめ

Gatsby + Netlify CMSは以下の点で最高。

  • Reactをフルに使って機能拡張できる
  • フロントエンドのナウい技術が使われている(PWA, SSR, GraphQLあたり)
  • 記事をmarkdownで管理できる
  • 実装をミスってもちゃんとロールバックされて、本番環境はバグらない
  • サイト公開まで一瞬
  • HTTPS、カスタムドメイン設定も簡単

逆にちょっとメンドくさいと思った点。

  • よくセッションが切れて、書いていた内容が吹き飛ぶ
  • 一般的なブログのレベルまで到達させるには、最初にそこそこ実装しないといけない
  • データがGitHubベースで保存されるので、フックしてGitHubサイドに反映されるまでちょっと時間がかかる

しかし、総じて良いなと思いました。
フロントエンドエンジニアとしてのポートフォリオになりそうです。