Next.js × TailwindCSS × microCMSでサイトをリニューアルしてみた
はじめに
自分が所属するボードゲーム制作サークル「デバッグモンキーズ」のサイトをリニューアルしました。
そこで採用した技術についての理由や、実装するにあたっての気づきを書いていきたいと思います。
作成したサイト
サークルで作ったゲームを一覧として紹介するシンプルなサイトです。
GitHubリポジトリはこちら
リニューアルの動機
このサイトは、5年ほど前にVue CLIでSSGで作っていました。
当時の自分はSPAについての知見があまりない状態で、「とりあえずさわってみたい!」というパッションでサイトを作っていました。
あまりVue CLIを使いこなせている感じがなかったのですが、なんとか形にし、以降新作のゲームを出すたびに更新を続けていました。
しかしこのサイトは一つの欠陥を抱えていました。
開設当初はCMSを使うという発想がなく、サイトの記事情報を一つのjsonファイル管理していました。
例えば「パピトー」というゲームを追加する場合、以下をjsonファイルに追記して更新することで運用していました。
{
"papito": {
"title": "PAPITO パピトー",
"article": [
{
"leadCopy": "ジジ抜きをベースにした推理×協力ゲーム!"
},
{
"imgpath": "img_detail_papito_01.png",
"title": "あらすじ",
"text": [
"『Show Must Go On!!』",
"ぬいぐるみたちのサーカス「パピトー」は、巷で一躍有名になっていた。",
"ある日、ショーの本番開始前に厄介ファンたちにぬいぐるみがさらわれてしまった!",
(中略)
]
},
{
"title": "ゲームの概要",
"text": [
"このゲームは、ジジ抜きをベースにした推理 × 協力ゲームです!",
"ざっくりとですが、このゲームの流れをご紹介します!"
]
},
〜〜〜以降、セクションごとに記事の中身の文章が記載される〜〜〜
記事の中身をjsonで管理しているのですが、改行ごとに文章を分けていたり、文中のスタイリングが当てられなかったりと、非常に運用がしづらい状態となっていました。
また、サークルメンバーは4人いるのですが、コードを触れる人が自分しかいないため、サイトの簡単な更新をしたくても自分が忙しくて動けなかったりすると、ボトルネックになってしまうという問題がありました。
そこで、このサイトの更新をCMSで完結させたいという思いがあり、サイトをリニューアルすることを決意しました。
ついでに学習の意味も込め、App Routerなどの最近のトレンドも取り入れてみようと思いました。
使用した技術
このサイトで使っている技術は以下になります。
Next.js
Next.jsではApp Routerを使用しました。
基本的にはReact Server Component(RSC)を使用する方針とし、やむを得ない場合のみReact Client Component(RCC)を使用します。
サイトの構成としては「一覧ページ」と「ゲーム記事ページ」の二つに分かれる構成となっています。
各ページをMicroCMSの情報と紐づけて、動的に中身が変更されるように構成しています。
TailwindCSS
スタイリングはTailwindCSSを使用しました。
最近「Tailwind CSS実践入門」を読み、ユーティリティファーストの考え方に感銘を受けたため採択しました。
TailwindCSSのHeadlessUI
HeadlessUIは、TailwindCSS公式が提供している、アクセシビリティ対応もしてくれている便利UIコンポーネント集です。
サイトのヘッダーメニューではHeadlessUIの「Popover」を使用しました。
HeadlessUIはRCCのみ使用可能なため、RCCのHeaderClientコンポーネントでヘッダーメニューの中身を実装し、RSCのHeaderコンポーネントでそれを呼び出しています。
Menuとの違い
Popoverと似た見た目のコンポーネントで「Menu」があります。
Menuはボタンにはタブでfocusできますが、中の選択肢にはfocusしないという特徴があります。
代わりに、メニューを表示させている状態で矢印上下キーで選択肢を選択できるようになっています。
ナビゲーションメニューではメニュー内部もfocusできるPopoverの方が適しています。
App RouterでPopoverを使用する際の注意点
App RouterでPopoverを開いている状態でPopoverコンテンツ外をクリックした時にPopoverが閉じないというバグがありました。今のところ対策用のdivを親階層に追加することでしか解決できないので注意です。
参照:HeadlessUIのissueコメント
MicroCMS
MicroCMSでゲームの情報を管理し、「ゲーム一覧」と「ゲーム記事ページ」の中身はゲーム情報APIから動的に生成します。
MicroCMSから読み込んだ記事のスタイリング
MicroCMSではリッチエディタかHTML記述を選べるように設定しています(組み合わせも可)。これにより、特定のIDを指定などをしたい場合はHTMLで記載することが可能です。
参照:Title: リッチエディタを使いつつ一部はHTMLで入稿する | microCMSブログ
MicroCMSのリッチエディタで作成した記事はhtml-react-parserでDOMに変換後、@tailwind/typographyを使用してスタイリングします。
これはTailwindCSS公式が提供する、タグ要素を適切にレイアウトしてくれるライブラリです。
さらにカスタムが必要であればprose
でクラスを指定、またはtailwind.config
にprose
の指定を記述します。
例:lg:prose-h2:text-3xl
などで指定すれば、PCサイズでh2のテキストだけを大きく設定することができます。
microCMSから型を抽出する方法
以下の記事を参考に実装しました。
API設定 > APIスキーマ > 「この設定をエクスポートする」
で出力されるjsonファイルをsrc/schema
配下に格納し、generate:cms types
コマンドを実行すると、src/types
配下に型が出力する仕様にしています。
ファイル名からエンドポイント名を取り出すので、スキーマのファイル名は変更しないようにします。
フォルダ上に同じエンドポイント名のファイルがある場合は、ファイル末尾の日付から最新のものが選択されるようです。
ホスティング
ホスティング先についても今回のリニューアルを機に変更しています。
以前はNetilifyを使用していましたが、今回から、AWS Amplify × Route53に移行しました。
最初は引き続きNetlifyでいこうと思っていたのですが、試したところApp RouterでSSR環境のビルドをしたところ、どのページも404になるバグが発生しました。
Netlify公式でもApp Routerに対応しているということが書かれていたのですが、どうにも解決できませんでした。(Redirectsの設定などいろいろいじって試しましたが、どれもうまくいきませんでした。)
やむを得ずAWS Amplifyに移行したところ、特に大きなエラーもなくビルドすることができました。
まとめ
今回Next.js×TailwindCSSで初めて実装をしてみて、想像以上に開発体験がよかったです。
TailwindCSSについて学ぶ前は、クラス名が長くなるし見づらくなってしまうので、微妙なのでは?と思っていたのですが、コンポーネントをうまく切って管理を分ければ、そこまで気にはなりませんでした。
むしろ、クラスの名命から解放される気持ちよさがありました。
TailwindCSS公式が提供するライブラリも豊富で、MicroCMSから取得した記事のスタイリングもスムーズにできたのが嬉しかったです。
また、初めてMicroCMSを使ってみて、こんなにもわかりやすいCMSがあるのかということにも驚きました。
自分はドキュメント読まずになんとなくで使ってみて事故るという体験を幾度となく経験していたため、CMSには苦手意識があったのですが、microCMSはその苦手意識も克服できるぐらいUIがシンプルでわかりやすかったです。
※ドキュメントはちゃんと読みましょう!
余談
最後に、「デバッグモンキーズ」のボードゲームが絶賛販売中です!
メンバー全員が「面白い」と納得できるまでこだわってデベロップしているので、よかったら見ていってください!
▼春に出した新作です
最後まで読んでいただきありがとうございました!
Discussion