icon

kosui / ebiebievidence

このブログを Gatsby + Remark から Next.js + MDX + Contentful へ移行しました

2021/9/26

概要

私のこのブログの既存の問題点を述べた上で、それに対してどのように解決を図ったか述べます。

以下では御託をつらつらと並べておりますが、MDX の導入や Contentful との連携はさておき、Gatsby からの移行については私が Next.js をやってみたかったという気持ちが移行理由の多くを占めています。どうかその辺を心に留めていただいた上でお読み頂ければ幸いです。

抱えていた課題

Gatsby に関する私の不勉強

Gatsby と Next.js はいずれも React をベースとした静的サイトジェネレータとして著名であり、それぞれがお互いにない長所を有しています。

Gatsby は強力なプラグインシステムを有する一方で、このプラグインシステムに適切に乗っかるためにはこれに対する一定の理解が求められるように思います。フロントエンドに関する仕事や活動を私はほとんど行っていないため、私には個人ブログをいじる時にしか Gatsby に触れる機会がありません。そのため、気軽な機能追加をサクッと行おうとしても、恥ずかしながら「一歩進んだと思えば進んでいなかった」を繰り返すことになり、中々重い腰を上げる気が起きませんでした。

TypeScript を導入していない

従来の私の個人ブログには TypeScript が導入できていなかったため、これがさらにリファクタする気力を削ぐ要因になっていました。

Remark Custom Blocks による拡張の限界

Gatsby でマークダウンファイルをレンダリングする際には Remark とそのプラグイン gatsby-transformer-remark がよく用いられると思いますが、記事内に独自のカスタム機能を利用したくなることもしばしばあるかと思います。そこでよく利用されるプラグインとして gatsby-remark-custom-blocks があります。gatsby-remark-custom-blocks は remark-custom-blocks をベースとしていて、以下のような記法で指定したクラスを持つ div 要素を生成することができます。

[[foobar | タイトル]]
| おはよう
| こんにちは
| こんばんは
<div class="custom-block foobar">
<div class="custom-block-heading">タイトル</div>
<div class="custom-block-body"><p>おはよう<br>こんにちは<br>こんばんは</p></div>
</div>

しかし、この要素内にコードブロックを埋め込もうとすると以下のように | を続ける必要があり、さらにこれをネストさせるとそれなりに可読性が下がるという問題がありました。入力に取れる要素もタイトルと本文のみであり、実装できる機能が制限されるケースもあります。

投稿コストが高い

これまで私は CMS を利用しておらず、記事に関する元ファイルはすべて GitHub 上にホストし、記事の執筆はすべて VSCode で行っていました。しかし、画像のアップロードや下書きの管理が面倒で、投稿までのハードルがそれなりに高い状況が続いていました。

解決策

Next.js への移行

どうせリファクタするならこのシルバーウィークにコンテンツ以外をすべて新しく作り直してしまおうと考えました。加えて、せっかくなら今まであまり利用したことがない Next.js を試してみようと思いました。Next.js は Automatic TypeScript configuration and compilation を謳っていて、チュートリアルやドキュメントでも TypeScript プロジェクトに向けた解説が数多く記載されているため、まずは試してみることにしました。

Gatsby からの移行にあたっては、Next.js 公式の移行ガイド を参考にしました。

ただ、結局はフレームワークを使う以上、その中身を理解している必要があることには変わりなく、Next.js の内部構造に対する理解をこれから深めていく必要があると思いました。

MDX への移行

MDX は Markdown の拡張であり、自分で定義した React コンポーネントを MDX ファイルの中で利用することができます。

Markdown を拡張する MDX はドキュメント作成の新たな可能性?

これにより、記事内により複雑な機能を持つコンテンツを追加することができるようになりました。

以下を参考に移行しました。

Remark から MDX への移行では、Markdown ファイルに記載された HTML タグを JSX として適切な形に変換する必要があります。特に class 属性や style 属性には注意が必要です。

Contentful との連携

ヘッドレス CMS を採用することで、気軽にサクッと書きたい記事はヘッドレス CMS で、プレビューを行いながらしっかり書きたい記事は手元で書けるようにしました。ちなみに、これまでの記事に関するファイルは引き続き GitHub 上に置いています。

特に Contentful は無料ユーザから有料ユーザへの移行もシームレスに行える上に、エクスポートツールなども用意されていて安心して使えそうだと思いました。また、Gatsby や Next.js での Contentful の利用方法は広く共有されているため、導入もスムーズに行うことができました。

Contentful 公式のページにて Contentful の Next.js への導入方法が記載されているため、チェックしてみて下さい。

その他

  • react-helmet から next/head へ移行した
  • RSS フィードの生成は catnose99 さんの記事 を参考にした
    • ただしすべて SSG したかったので getStaticProps の時に生成した
    • 今書いていて気が付いたが getStaticPaths でやるべきだったのでは

おわりに

コンテンツが少なかったことや個人ブログということもあってやや横暴な技術選定を行った背景もあり、基本的な機能の移行に掛かった時間は合計で 7 時間程度とかなり短く済みました。

ただし、目次の生成や Google Analytics の導入が完了していないため、それらを行う予定です。この辺は Gatsby ではプラグインが全て行ってくれるので、やはりその辺は Gatsby の強みだなと思いました。

@kosui_me
19 年に DeNA 入社。23 年にカケハシ入社。現在は、薬局向け SaaS の認証認可基盤を良くしていくお仕事をしています。