ELW株式会社 テックブログ

リアルなログをそのままお届けします。

Tanstack Router

今回のフロントエンド勉強会では、話題のルーティングライブラリ TanStack Router を取り上げました。

現在、弊社で開発中のプロダクトにおいて採用を検討しており、要件を満たせるかどうかの観点から調査を行いました。今回はその中でも、導入前に最低限押さえておきたいポイントに絞って、公式ドキュメントや関連リンクとともに紹介していきます。

型安全なrootingとsearch parameter

TanStack Routerは、Next.jsとは異なり、ルーティング定義におけるユーザー定義型の自動補完が特徴です。たとえば、useNavigate() や useParams() などの公式Hooks、 コンポーネントでは、あらかじめ定義したルート型が自動的に補完され、型安全にルーティングできます。

tanstack.com

この型補完の仕組みがどのように実現されているかについては、以下の記事がとても参考になります。

www.romaintrotard.com

Search Paramsの型安全な継承

TanStack Routerでは、親ルートで定義したsearch paramのバリデーションを、子ルートで安全に拡張・継承できます。

Parent routes can define shared search param validation. Child routes inherit that context, add to it, or extend it in type-safe ways. This makes it impossible to accidentally create overlapping, incompatible schemas in different parts of your app.   tanstack.com

この仕組みにより、アプリ全体で 整合性のあるsearch parameter管理 を実現でき、スキーマの衝突も防げます。

data loading、route lifecycle、SSRの理解

TanStack Routerを理解する上で最初に読んでおきたいのが、ルートのライフサイクルについて解説された以下のページです。

tanstack.com

loader や beforeLoad がどのタイミングで実行されるのかを把握することで、データ取得とルーティングの設計がより明確になります。 あわせて、下記の記事も beforeLoad と loader の使い分けを整理するのに役立ちます。

benhouston3d.com

TanStack Queryとの統合

TanStack Routerは、TanStack Queryとの親和性が高く、ルートごとのデータ取得に活用できます。

tanstack.com

  • loader 内で queryClient.ensureQueryData() を使って事前フェッチ
  • クライアント側では useQuery や useLoaderData を併用し、キャッシュから再利用

この構成により、SPAとSSRのどちらにも対応したデータ取得パターンを構築できます

Router Contextの設計

プロジェクトが大規模化するにつれて、認証情報やテナントIDなどの共通ロジックの持ち回りが必要になります。 その際に活躍するのが router context です。

tanstack.com

設計段階から必要な共通データの構造を定義しておくことで、ルートごとの処理をより柔軟に行えるようになります。

SSRに関する注意点

TanStack Routerは、SSR(Server Side Rendering)にも対応していますが、現時点では制御にやや注意が必要そうです。 たとえば、ssr: false や defaultSsr: false に設定しても、loader や beforeLoad がサーバー側で実行されてしまうケースがあります。

github.com

このような場合、暫定的な対処としては typeof window === 'undefined' を使った条件分岐が有効ですが、将来的なアップデートによる改善に期待したいところです。

まとめ

実際に触ってみた印象としては、開発体験(DX)が非常に高く、コードを書いていて楽しいと感じました。

また、ライブラリとしてはまだ新しいながらも、単純なパフォーマンスや型安全性の高さが非常に魅力的で、導入に対する費用対効果も十分に見込めそうです。

今後のアップデートで追加予定の機能や改善点も多く、将来性の高いライブラリとして注目し続けたいと思います。