Next.js+Vercel+microCMSでブログをリニューアルしました

表題の通り、リニューアルしました。こっそり2週間くらい前から反映させてます。

背景

もともとこのブログはHugo + GitHub Pagesで構築しておりました。

Hugo, Github Pages, CircleCIつかってブログ構築 - abekoh's tech note

これでも機能は十分でしたが、

  • すべてGitHub Pages上にリソースを置いていた(画像も含めて)ので、リポジトリ自体のサイズ肥大化が気になる(個人ブログレベルなので大したものではないが)
  • Hugoのテンプレそのまま使っており、フロント知識あまり身に付けず運用できている
  • カスタマイズはGo Templateを用いたものを触る必要あり。個人的に気分が乗らない…

といったことが不満でした。

情報漁ると、最近はNext.js + Vercel + microCMSといった構成が一つの流行りらしく、モダンなフロントまわりの勉強がてらこの構成で構築してみることにしました。

参考資料

構築についてはこれらの記事ほぼそのままです。

microCMSは公式のチュートリアルが充実しており、他にもたくさん参考できそうなところが多そうでした。

またReactと最近のJavaScript/TypeScriptに関しては、ここでも紹介した通りこの同人誌が非常に参考になりました。

Next.jsについては公式Doc、ときどきググってみるって感じで

デザインフレームワークはMaterial-UIを採用しました。


さらに、最近のHTML/CSSまわりの情報をこの本ざっと読んでキャッチアップしました。
かなり知らない記述方法など知れてよかったです。SEOだけでなく、iOS向け、Android向け、Twitter/Facebook共有用のためのmeta/link設定など非常に多くあってびびりました。

Tips

構築していく上でつまづいたところ、力入れたところなどをいくつか紹介します。

Material-UIをNext.jsで使う

Material-UIをNext.jsといったSSRなフレームワークで利用する際、一工夫が必要となります。

公式にも書かれている通り、リクエストごとにServerStyleSheetsをサーバーサイドで生成、CSSとして埋め込むといったことをしないといけないようです。
Next.jsでのサンプルもここにあります。

罠でハマったのが、<Head>のimport元。
下記のように_document.tsxで呼ぶ場合とそれ以外で異なり、間違ってると正常にページが表示されませんでした。

// _document.tsx
import { Head } from 'next/document';
// _app.tsx など
import Head from 'next/head';


各種環境向けアイコン/favicon

faviconといえば昔はfavicon.icoひとつ置くだけでOKでしたが、今はスマホ用ブラウザ用など規格が乱立しているようでした。
このGeneratorを使って一発で作成→設定することができました。

プレビューや設定されてるかチェックする機能もあって便利です。

技術系タグにアイコンをつける

こだわりポイントです。
deviconというOSSに、さまざまな技術スタックのアイコンが用意されてます。

これを_document.tsxにてインポートしておいて

<Head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/devicons/devicon@v2.11.0/devicon.min.css">
</Head>

Material-UIのIconコンポーネントで利用するようにしてみました。タグ自体はChipを用いてます。

<Chip
  icon={tag.icon ? <Icon className={tag.icon}></Icon> : undefined}
  label={tag.name}
/>


Next.jsでRSSやsitemap.xmlなど設定

こちらの記事が参考になりました。

JSX/TSXで他のページと同様に作ってしまえるので管理が非常に楽です。

OGP画像を動的に生成

OGPとはOpen Graph protocolのことで、TwitterやFacebook、Slackにリンクを貼り付けたときに見える画像やテキスト情報についての規格です。
次の記事を参考に、canvasを使って動的に生成するようにしてみました。


この記事のOGP画像は次のリンクに設定しています。
https://blog.abekoh.dev/api/ogp-images/build-blog-with-nextjs
タイトルをASCII文字なら幅2、それ以外なら幅1としてカウントし、適当なところで改行するようにしてみました。

まとめ

特にReact/Next.jsの知識が身についてきて楽しかったです。
まだまだ改良したい部分があるので、引き続きブラッシュアップしていきます。