コキチーズのホームページ

FirebaseとNetlify CMSでブログを作る

March 30, 2020

FirebaseとNetlify CMSでブログを作る

k2wanko.dev ドメインを取ってからあんまり活かせてなかったのでブログで使ってみようかなと考えていて、じゃあブログシステムはどうしようかなと思っていたところにNetlify CMSがよさそうだなと知ってとりあえず使ってみることにしました。

最近Mediumやnoteで記事を書いてて思ったのはMarkdownで長文書くのはエディター支援がないとつらいなーと思っていたところだったので

Netlify CMSとは

Netlify CMS

Netlifyが作るOSSのCMSです。SPAで動作をし、GitHubと連携すると直接GitHubにコミットしてブログを書いたり、ドラフトとしてPull Requestを作ってくれたりします。GitHub以外にもGitLabとの連携もできます。

書き出されるファイルはMarkdownなんですがこのようにリッチなテキストエディタもついています。

今回はNetlify CMSをCMSとして使いGatsbyをフレームワークにし、Firebase Hostingにデプロイしてみます。
GitHub Pagesもいいかもと思ったんですが、ビルドした成果物をコミットする必要もないし認証にFirebase Authenticationを利用するので慣れているFirebase Hostingを利用します。

Setup

まずはGatsbyのセットアップを行います。次のコマンドでGatsbyのCLIをインストールします。

npm install -g gatsby-cli

そしてgatsby-cliを使ってブログの雛形からディレクトリを生成します。

gatsby new blog https://github.com/gatsbyjs/gatsby-starter-blog

次にgatsby-plugin-netlify-cmsをインストールします。

npm install --save netlify-cms-app gatsby-plugin-netlify-cms

gatsby-config.jsに追記します。

plugins: [
  {
    resolve: `gatsby-plugin-netlify-cms`,
    options: {
      modulePath: `${__dirname}/src/cms/cms.js`,
      manualInit: true,
    },
  },
]

src/cms/cms.js は次のような形でファイルを作成してください。 このコードで動作環境に応じて設定を書き換えることを目的にしています。 base_url は常に動作している環境のoriginを向くようにしています。

import CMS from "netlify-cms-app"

CMS.init({
  config: {
    backend: {
      base_url: window.location.origin,
    },
  },
})

次にNetlify CMSの設定ファイルを作成します。今回の場合は static/admin/config.yml に作成します。 {username} にはホストする予定のGitHubのユーザー名か、Orgの名前を指定してください。blog部分も任意のリポジトリ名で大丈夫です。 auth_endpoint は後ほど解説します。

backend:
  name: github
  repo: {username}/blog
  auth_endpoint: /auth
  api_root: https://api.github.com

media_folder: static/img
public_folder: /img

collections:
  - name: "blog"
    label: "Blog"
    folder: "content/blog"
    create: true
    slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
    editor:
      preview: false
    fields:
      - { label: "Title", name: "title", widget: "string" }
      - { label: "Publish Date", name: "date", widget: "datetime" }
      - { label: "Description", name: "description", widget: "string" }
      - { label: "Body", name: "body", widget: "markdown" }

この設定では次のようなファイルパスで記事が作成されます。 content/blog/{{year}}-{{month}}-{{day}}-{{slug}}.md gatsbyでビルドする際に全くファイルがないとビルドに失敗するので適当にファイルを作成しておきましょう。

Netlify CMSのバックエンドにFirebase 認証を利用する

デフォルトではNetlify CMSはNetlifyのAPIを使ってGitHub認証をサポートしてくれますが、それ以外だと自前でサーバーを用意する必要がありそうで、Firebaseでできる方法がないか調べたところ
Cloud Functionsを使ってNetlify CMSの認証をしているサンプルがあり、中を見てみたらどうもGitHubのトークンさえ渡せればいいだけで自分で一切サーバーを持たなくてもなんとかなりそうだったのでその方法を紹介します。

Herohtar/netlify-cms-oauth-firebase: Firebase Cloud Function based OAuth2 GitHub backend for Netlify CMS

Netlify CMSにログインするときはGitHubのログインボタンを押すとポップアップが出てきます。このポップアップウィンドウとpostMessageでGitHubのトークンを渡せばよいようです。

ポップアップウィンドウのpathはstatic/admin/config.ymlauth_endpointで指定します。

今回はGatsbyで作成を行っているのでsrc/pages/auth.jsにファイルを作成しポップアップウィンドウで開くページにします。

まずauhotizing:githubを送ってGitHubの認証を開始します。

window.opener.postMessage(`authorizing:github`, "*")

Firebaseのリダイレクト方式でGitHubのサインインを行います。

const provider = new firebase.auth.GithubAuthProvider()
      provider.addScope('repo') // 必要なスコープを追加
      firebase.auth().signInWithRedirect(provider)

無事にサインインが完了すると次のコードでGitHubのトークンを取得できます。result.credential.accessTokenに入っています。トークンを再度postMessageでCMS側に伝達します。

firebase.auth()
    .getRedirectResult()
    .then(result => {
      if (result.credential) {
        const token = result.credential.accessToken
        window.opener.postMessage(
          `authorization:github:success:${JSON.stringify({
            provider: "github",
            token,
          })}`,
          location.origin // 送り先を自身のoriginに限定
        )
      }

これで認証はおしまいです。

FirebaseでのGitHub認証については公式のドキュメントを確認してみてください。

Authenticate Using GitHub with JavaScript | Firebase

あとはnpm start でDevサーバーが起動し http://localhost:8000/admin にアクセスし、GitHubログインできれば完了です。

Netlify CMSのTop

まとめ

まだ、使いだしてみて間もないのでNetlify CMS自体の使いやすさは触れませんが、この記事の執筆に利用してみてますが日本語入力時の挙動が怪しかったり、画像の添付がファイルへのコミットになるのがちょっとイケてないかなーと思っています。ただ幸いなことに、Pluginを書くのはさほど苦じゃない気がするので自分でカスタマイズできるかどうか今後試していきたいと思います。

ちなみにこのサイトはGitHubで管理しているので、気になる人はそっちも合わせて確認してみてください。


コキチーズ
千葉県で暮らすエンジニア