thinceller blog

Next.js + Chakra UI + MDX でブログを作った

2021-11-25 公開

技術系のアウトプットをするとき、基本的には 自分の Scrapbox に雑に書いて満足することが多いです。

自分にとっては情報や思考を整理しながら書き進められるScrapboxはとても心地よいのですが、 人に見られる前提の文章を書くことを避けがちな自分を矯正するためにも、まずはハードルの低い個人ブログで記事を書く癖をつけようと思いました。

GatsbyやHugoなどの静的サイトジェネレータを利用してもいいのですが、自分が好きなNext.jsをベースにしてブログを作ってみることにしました。

技術スタック

今回利用した技術は以下の通りです。

  • Next.js
  • Chakra UI
  • MDX

それぞれの技術について軽く説明していきます。

Next.js

Reactのフレームワークとして今やファーストチョイスになることも多くなってきたNext.js です。

特に何も考えることなくパフォーマンス最適化を受けることができるため、個人ユースでも手軽に感じています。

公式が提供している多くのexampleも痒い所に手が届きますし、 このブログも with-mdx-remote のexampleがベースになっています(というのは結果論で、自分で構築していたらexampleとほぼ同じになりました)。

Examples | Next.js

Chakra UI

Chakra UI は「コンポーネントの一貫性を保つ」ことを念頭にデザインされたコンポーネントライブラリです。

詳細な設計原則の説明は 公式のドキュメントに譲りますが、 洗練されたAPIに型安全にアクセスできるので一貫したスタイルを持つことがかなり容易になっているように感じます。

個人的に好みなのは <Stack><Center> などのレイアウト系のコンポーネントが充実している点です。 <Stack> はflexboxを抽象化したようなコンポーネントで、子要素を均等に並べたり子要素の間のスペースやdividerを手軽に定義でき、 <Center> は子要素を単純に中央寄せさせるコンポーネントです。 CSSをほぼ書くことなくこういったレイアウトを実現できるのはとても便利です。

後述するMDXから変換されるコンポーネントにChakra UIを適用することで、 ブログコンテンツ内、あるいはブログコンテンツ部分とその他の部分のスタイルの一貫性を保つことができています。

MDX

当初は素のMarkdownで記事を書き、markdown-itかremarkのようなライブラリでHTMLに変換して dangerouslySetInnerHTML を使う方式を取る予定でした。 しかし、ブログコンテンツ内で next/linknext/image を使おうとしたときに少々手間がかかりそうでした。

Markdown のサイト内リンクを Next.js の Link にしたい でも述べられていますが、 解決手段としてはMDXを使うか remark-reactrehype-react を利用する方法があります。

MDXは最近 beta 版が公開された React の公式ドキュメントでも利用されており、個人的にも興味があった技術なので今回採用してみることにしました。

Next.jsでMDXを利用する方法はいくつかあります。

  • @mdx-js/loader(MDXのためのWebpack loader)
  • @mdx-js/mdx(MDXをコンパイルできるライブラリ)
  • @next/mdx(Next.js公式の @mdx-js/loader の薄いラッパー)
  • next-mdx-enhanced(hashicorp社製の @mdx-js/loader のラッパー)
  • next-mdx-remote(hashicorp社製の @mdx-js/mdx のラッパー)
  • mdx-bundler(esbuildを使ってMDXをコンパイル・バンドルするライブラリ)

これらのライブラリの比較は Comparison of MDX integration strategies with Next.js - DEV Community 👩‍💻👨‍💻 などの記事が参考になります。

このうちのいくつかを試してみましたが、最終的に next-mdx-remote を利用することにしました。

next-mdx-remote は非常にシンプルなライブラリとなっており、MDXをシリアライズして getStaticProps からコンポーネントに渡しやすいAPIを提供してくれます。 一方でただのコンパイラであるためにReact Componentのimportを解決できませんが、代わりにパフォーマンス的に良好であるらしいので記事が増えてきてもデプロイ時間で悩むことはなさそうです。

まとめ

Next.js、Chakra UIやMDXを使うことで、ほぼスクラッチでありながらそれなりに整ったブログを簡単につくることができました。 最小限の実装だけを行って本記事を書いているので、今後は様々な機能を追加していきつつそれを記事にしていくことを目指します。