Next.js App RouterとPayload CMS を使ってブログを構築した
Webやフロントエンド開発の技術についてある程度理解すると、自分でWebサイトを作りたくなるものです。かく言う自分もアプリ開発の仕事をしながら、実際に自分でWebサイトも運営してきました。
そんな中で、年末年始の休暇を利用してブログサイトで使っている技術構成を一新しました。本記事では、その技術選定や実装プロセスについて共有します。
当初の予定は3日でした。しかし、度重なる変更のため、完了まで1週間を要しました。
以前使っていたブログの技術構成
本題へ入る前に、以前使っていたブログの技術構成を紹介します。
- Next.js Page Router
- CSS in JS (Emotion) によるスタイリング
- Markdownファイルでコンテンツを管理
- Vercelに本番環境をデプロイ
2019年の構築構成は、マークダウンファイルを更新するだけというシンプルさでした。そのため、個人の運用でも全く問題ありませんでした。
上記の技術構成でも、Webサイトの表示速度といったパフォーマンスは良好でした。しかし、運用を続ける中で以下の課題が明らかになりました。
- コンテンツ管理システム(CMS) がなく、コンテンツ量が増えるにつれて管理が煩雑になる。
- コンテンツ量が増えるにつれ、更新時の静的サイト生成にかかる時間が増加する。
今回構築したブログの技術構成
それでは、今回新たに採用した技術構成を紹介します。
- Next.js App Router
- CSS Modulesによるスタイリング
- Payload CMSによるコンテンツ管理
- GraphQLを使い動的にコンテンツを表示
まず、コンテンツ管理システム(CMS) がなかったので、今回はPayloadというCMSを導入しました。 これでWeb上のUIを通してコンテンツを管理できるようにしました。
また、技術スタックも最新のトレンドを取り入れたものへ更新しました。例えば、2023年にリリースされたNext.js App Routerへの移行などです。採用した技術については以下で詳しく説明します。
フロントエンド
Next.js App Router
2023年にリリースされたNext.js App Routerで今回はフロントエンドを構築しました。
現段階で、Page Routerから全面的に乗り換える必要性はまだ高くありませんが、今後使うことが増えるのは確実なので勉強も兼ねています。
App Routerに関しては、Layout 専用のコンポーネントが備わりレンダリングの最適化が簡単に行えるようになるなど、実用的なアップデートも多数備わっています。その一方で、新規導入されたServer Componentsなどノウハウが十分に溜まっていない部分も多く、安定して高速に開発できる段階にはまだ達していません。
App Router自体、まだリリースされて間もないので手探りの部分も多いですが、運用していくにつれてより洗練されてくることでしょう。
スタイリング
UIのデザインの細かいスタイリングは自分で行いたかったので、枠組みが用意されているTailwind CSSはまず候補から外れました。
CSS ModulesとCSS-in-JSで悩みましたが、最終的にCSS Modulesを選びました。
CSS-in-JS自体は数年前から使っており使用経験はありました。しかし、近頃React開発チームが力を入れているServer ComponentsとCSS-in-JSの相性の悪さに関する懸念を拭えず、今回はCSS Modulesへの移行を決めました。
GraphQL Client
コンテンツデータの取得にはGraphQLを使用するため、クライアントとしてURQLを選定しました。
- Apollo Client:
- ユーザー数が多く、ドキュメントも充実している
- Relay:
- クライアントサイドのReactで使うのに向いている
- サーバーサイドレンダリングやNode.js上で使う際の例が少ない
- URQL
- バンドルサイズが一番軽量
- サーバーサイドレンダリングやNode.js上での動作も保証されている
今回はサーバーサイドレンダリングの際にデータを取得する必要があったので、その中で一番軽量なURQLを選びました。
国際化・多言語化対応 (i18n)
Next.js Pages Routerではビルドインでサポートされていた国際化・多言語化対応 (i18n) ですが、App Routerではガイドは用意されているものの、対応自体は自分で行う必要があります。
今回は next-international というライブラリを使って対応しました。
このライブラリを選択した理由は、App Routerに対応していたことと、軽量かつ型安全であるためです。
パフォーマンス
Next.js App Routerの Layout 機能やCSS Modules移行によるスタイリング用のコード削減でパフォーマンスは多少改善されています。
250msほどの短縮が計測できましたが、正直なところ体感できるほどの違いはありません。
CMS・GraphQL サーバー
フレームワーク
当初はContentfulなどのサービスとして展開しているHeadless CMSを使うことも検討していました。
ただ、長期的に使うことを考慮し、自前でサーバーを立てて管理できるオープンソースのHeadless CMSを使うことにしました。
しかし、オープンソースで利用できそうなHeadless CMSの選択肢は少なく、以下の2つから選ぶことになりました。
どちらの候補も、JavaScript/TypeScriptで書かれたオープンソースのCMSフレームワークで、GraphQLやREST APIをサポートしているなどの共通の特徴を持ち合わせています。
Strapiの使用経験はありました。しかし、Payloadと比較してコード記述は煩雑で、型安全も不十分でした。開発体験の観点から、今回はPayload一択となりました。
Payload自体は、利用可能なデータベースがMongoかPostgre(ベータ版)に限られるなど、まだまだ開発段階である印象は否めません。しかし、Strapiと比較して少ないコード量でCMSを構築でき、TypeScriptの型安全にも配慮されているため、開発体験は良好です。
まとめ
以前使っていた技術構成で実現できなかった機能を実現できたので、総合的には満足しています。
運用していると分かってくる改善点もあると思うので、継続的にアップデートしていきたいですね。
