【ゆるく使うNext.js】App Routerは全部use client;にすればReactの機能を気軽に使えるので個人開発にオススメ【Client Components】

※かなり短いゆるめの記事です。

はじめに

この記事の着想はmasakinihirotaさんのツイートからアイデアを得たものです! ありがとうございます!

TL;DR

Next.jsは「Reactのプラスα」的な使い方をすれば、個人開発の規模感でも使いやすい。

経緯

個人開発の用途でNext.jsに触れているのですが、バージョンが上がるに従ってどんどん新しい機能が増えていて、キャッチアップに困っていました。

具体的には、ねりけしさんのこのツイートと同じ悩みを抱えていました。

ねりけし @nerikeshi_k
個人開発物Next.jsで作ってるけど日和ってpage routerにしてしまっている。個人開発物ならばapp routerを試すべきでは とも思いつつ、でも自分のモチベは限りある資産(?)だから、技術的な挑戦はリリースまで辿り着けそうな上限に絞る必要があると信じているので、日和ってしまってる(二回言う)

https://twitter.com/nerikeshi_k/status/1715357927383716284

App Routerを使うかPage Routerのままにするか、Server ComponentsとClient Componentsをどのように使い分けるか、Server Actionsを導入するか……覚えることがたくさんあって混乱していました。

Reactについては「ちょっとデキる」ですが、Next.jsについては「何もわからん……」という状態でした。*1

任天堂横井軍平さんの名言に「枯れた技術の水平思考」という言葉がありますが、これは個人開発にも当てはまります。ある程度落ち着いている技術のほうが、素早く開発できます。

技術的挑戦はとても大事です。しかし、「一つのプロダクトを自分一人で最後まで作り切る」という目標の達成においては、ある程度落ち着いた技術のほうが開発しやすいのも事実です。

そんな中、偶然見つけたのがmasakinihirotaさんのツイートでした。

masakinihirota @masakinihirota
Next.jsで高性能にする意味がないなら page routerのままでいいと思う。最先端の機能が使いたい、高度なことに挑戦したいというのならApp routerを使えばいいと思う。もしくはrootに'use clinet' ディレクティブ置いて全部クライアントにすればいいんじゃないかな?
App routerのディレクトリでのルーティングのほうが直感的で使いやすい。 App routerは、真面目に使おうと思うとかなり高い壁になるとおもう。サーバークライアントはもちろんmiddlewareとかも絡めて考えなきゃいけなくなるからね。

https://x.com/masakinihirota/status/1710969004972703751?s=20

このツイートは自分にとってコロンブスの卵のようなツイートでした。

このおかげで、自作サービスにおけるNext.jsの開発方針を決定できました。

開発戦略

戦略はとてもシンプルです。

まずはClient Componentsのみでアプリを作ってみます。

つまり、App Routerの状態でトップレベルのコンポーネント(root)にuse client;をつけて、全てのコンポーネントをいったんClient Componentsにします。

開発を進めていけば、自然と静的に表示したい箇所が増えてくるはず。

そこから徐々にServer Componentsの領域を増やしていけばOK!

データの取得方法も、useSWRを使ってまずはCSR(クライアントサイドレンダリング)から始めてみるのがオススメです。*2

まとめ

すごく単純なフローですが、このことに気がつくまで色々悩んでかなりの時間を費やしました。

ここから導き出せる一般法則は「新しい技術に触れるとき、まずは自分の詳しい領域のみを使って開発しよう」ということです。そして基本をガッチリと固めてから、徐々にエッジな技術を取り入れてみるのが良さそうです。

最近Rustについて調べていたときに @sadnessOjisan さんのこのツイートを見掛けました。

統合開発環境 @sadnessOjisan
Rust, 正直なところウェブサーバーを書くための言語としてならかなりイージー側の選択肢だと思うんだよな。所有権とかライフタイム無視して書いてもお釣りが来ると思うし、実はそんなに勉強しなくても書けると思う。DB周りの扱いはクセあるけど、それはどの言語も同じでしょとも思う。知らんけど。

https://x.com/sadnessOjisan/status/1726408490649006312?s=20

このツイートも慧眼だと思いました。つまり、所有権やライフタイムをすぐに使いこなせなかったとしても(Rustの全ての機能を使いこなせなかったとしても)、まずは自分の分かる範囲で使うだけでもメリットを享受できるということです。

新しい技術やスピードの速い技術に触れるとき、ついつい全てを理解してから触れてしまいがちですが、そんなに気負うことはなくて、まずは自分が理解しやすい範囲で使ってみる、というのが良いのだと分かりました。*3

話を戻すと、まずはCSR的な用途のみで使うことで最新のNext.jsでも安心して使えるのがこの開発方針のポイントです。

個人開発でNext.jsを使いたい方のご参考になれば幸いです。

ちょっと追記(2023-11-28)

Next.js周りのStackについて

以前、ブログ記事に「T3 Stackを使って開発をしてやるぜ!」みたいな内容のことを書いたのですが、これはこれで色々なデメリットが有ることが分かりました。

というのも、T3 StackはPage RouterとAPI Routesを前提にして作られています。*4

それぞれのライブラリがPage Routerと密結合している印象を受けました。自分はT3 Stackを使って途中まで開発していたのですが、Page RouterからApp Routerへの移行があまりに複雑で、素のNext.jsを使ってゼロから作り直すことにしました。

またtRPCはAPI Routesが前提になった作りになっていて、Route Handlersでは実装できません。

そして最新のNext.js公式は、API RoutesではなくRoute Handlersを推奨しています。

Good to know: If you are using the App Router, you can use Server Components or Route Handlers instead of API Routes.

API Routes can't be used with static exports. However, Route Handlers in the App Router can.

そのため、T3 Stackを使った状態でNext.jsのバージョンを上げたとき、最新の機能に合わせてコードを書き換えるのが難しいです。*5

これはNext.jsの技術の進展が速いことが理由です。つい先日まではAPI Routesを新機能として勧められていた気がするのに、いつの間にかRoute Handlersが推奨になっていました。

Next.jsの技術の進化は素晴らしいと思いますし、なんだかんだとても使い勝手は良いです。ただ、最新の機能をキャッチアップしすぎると、それだけで時間が溶けてしまい、肝心のプロダクト開発・機能追加に着手できないという問題があります。最近の個人開発のトレンドを見ても「Next.jsのApp Routerを諦める選択」は割りと多く見られる気がします。

つまり、何が言いたいかというと「ある時点でのNext.jsを前提にした技術スタックの塊」を使ってガチガチに構築すると、アップグレードが大変になるということです。

App RouterやServer Components, Server Actionsへの移行をスムーズにするには、外部のライブラリを使いすぎないという選択肢もアリだと思います。自分はそうするつもりです。

そのため、Next.jsの進化がもうちょっと落ち着くまで*6App RouterでClient Componentsを使うCSRを中心にした薄めのフロントエンドにしたほうが色々と困らないのではないかと思いました。Reactの基本的な機能に絞って使ったほうが、後々の開発で助かる気もします。*7

余談ですが、ReactやNext.jsがどのような歴史を辿ってきたのかについては、この記事に詳しくまとめられていてとてもオススメです。

zenn.dev

Next.jsから学ぶWebレンダリング ~React誕生以前からApp Router with RSCまでの流れ~

*1:ViteでのReact開発や、Deno/FreshのPreactでの開発はしたことがありましたが、それでもNext.jsはよく分からない状態でした。Island Architectureより難しい気がします

*2:Next.jsの場合、CSRのデータ取得でuseEffectかuseSWRを使いますが、後者の方をオススメします。詳細はこちら → https://nextjs.org/docs/pages/building-your-application/rendering/client-side-rendering

*3:まずは理解しやすいところから始めて、徐々に知見を広げていく

*4:T3 StackでApp Routerを使うオプションが最近導入されましたが、まだExperimentalです。

*5:Page RouterやAPI Routesを最新のNext.jsでも使えるため、あえてそのままにすることもできますが、個人的にはなんとなく居心地が悪いです……

*6:Server Componentsの機能はReactが将来実装する機能の先取りなのでガンガン使っても大丈夫だとは思います → https://ja.react.dev/reference/react/use-server また、使いこなせるかは別としてServer Actionsも個人的には大歓迎です。

*7:もちろん、これは個人開発における考えです。フロントエンド専門のチームがいる場合は、色んなStackをどんどん積極的に取り入れるのも悪くないと思います。