tanstackをstartする

2025年，毎月投稿2月号です．今回は型安全なルーティングが魅力のTanStack Routerのセットアップをサクッとできるtanstack Startを紹介したいと思います．

---
TanStackシリーズは，フロントエンド開発におけるライブラリ群です．
データ管理ライブラリTanStack Queryや，高機能なテーブル作成を補助してくれるTanStack Table，ルーティングをするTanStack Routerなどがあります．

TanStack Startを使うと，TanStack Routerなどがセットアップされたプロジェクトを素早く用意することができます．

ref: [TanStack | High Quality Open-Source Software for Web Developers](https://tanstack.com/)

---
# TanStack Startのはじめかた
:::note warn
警告
TanStack Startは執筆時現在(2025/02/27)，Beta版です．
:::

下記のコマンドで完了します. 最後のコマンドを実行すると`localhost:3000`からアプリケーションにアクセスできます．
ref: [Quick Start | TanStack Start React Docs](https://tanstack.com/start/latest/docs/framework/react/quick-start)

```bash
npx degit https://github.com/tanstack/router/examples/react/start-basic start-basic
cd start-basic
npm install
npm run dev
```

下記がセットアップされたプロジェクトを作成することができます．
- [Basic](https://tanstack.com/start/latest/docs/framework/react/examples/start-basic) (start-basic)
- [Basic + Auth](https://tanstack.com/start/latest/docs/framework/react/examples/start-basic-auth) (start-basic-auth)
- [Basic + Counter](https://tanstack.com/start/latest/docs/framework/react/examples/start-basic-counter) (start-basic-counter)
- [Basic + React Query](https://tanstack.com/start/latest/docs/framework/react/examples/start-basic-react-query) (start-basic-react-query)
- [Clerk Auth](https://tanstack.com/start/latest/docs/framework/react/examples/start-clerk-basic) (start-clerk-basic)
- [Convex + Trellaux](https://tanstack.com/start/latest/docs/framework/react/examples/start-convex-trellaux) (start-convex-trellaux)
- [Supabase](https://tanstack.com/start/latest/docs/framework/react/examples/start-supabase-basic) (start-supabase-basic)
- [Trellaux](https://tanstack.com/start/latest/docs/framework/react/examples/start-trellaux) (start-trellaux)

(ディレクトリイメージ)
![ss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2540179/ee4f8fd5-09ed-43bd-886c-bec44570c8fc.png)

(立ち上がるページイメージ)
![ss 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2540179/e46236ce-1c3d-43ba-8b6a-dfc7b77fcda7.png)

このアプリはサーバーサイドで動作しているので，ブラウザの`javascript`をoffにしても動作します．

(ブラウザのjava scriptをoffにしてる様子)
![ss 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2540179/96fe880e-0dd0-49b1-aeb3-5315c8bf3ffd.png)


# 構成の紹介
`app/router.tsx`にてreact-routerの設定をしています．この`routeTree`というのが，自動生成されるルーティングを型安全にしている本体です．

```app/router.tsx
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
import { DefaultCatchBoundary } from './components/DefaultCatchBoundary'
import { NotFound } from './components/NotFound'

export function createRouter() {
	const router = createTanStackRouter({
		routeTree, // これが自動生成されるやつ
		defaultPreload: 'intent',
		defaultErrorComponent: DefaultCatchBoundary,
		defaultNotFoundComponent: () => <NotFound />,
		scrollRestoration: true,
	})
	return router
}

declare module '@tanstack/react-router' {
	interface Register {
		router: ReturnType<typeof createRouter>
	}
}
```


このようにリンクに型が割り当てられ，存在しないリンクを指定できないようになっています．
(エディタで予測が出ている様子)
![ss 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2540179/53d88d8f-1372-48d6-9644-eb460743bcd3.png)

また，パスだけではなく，パラメータも型安全の恩恵を受けることができます．`app/posts/$postId`へと遷移するLinkタグに`postId`パラメータがないと警告が出ます
(パラメータがなくて型エラーが起きてる様子)
![ss 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2540179/b2e08646-ebc4-4157-bd05-44ea3222f743.png)


新しいrouteを作成してみます．
`appq/router/test.tsx`ファイルを作成してみると，まず雛形が自動作成されます．

また，routeTreeの方にも自動で変更が入ります．
```diff
const UsersRoute = UsersImport.update({
	id: '/users',
	path: '/users',
	getParentRoute: () => rootRoute,
} as any)

+ const TestRoute = TestImport.update({
+	id: '/test',
+	path: '/test',
+	getParentRoute: () => rootRoute,
+	} as any)

...
```

蛇足ですが，/testの部分を書き換えることはできません．書き換えても保存のタイミングで自動修正されてしまいます．

## 高度なルーティング機能と実践例

TanStack Routerは、シンプルなルーティングだけでなく，複雑なアプリケーションに必要な高度な機能を備えています．ここでは，いくつかの実践例と活用方法を紹介します．

### ネストされたルートの実装

複雑なUI構成では，共通レイアウトや部分的なエラーハンドリングを実現するために，　ルートをネストして定義するケースが多くなります．たとえば、ユーザー情報ページでは，概要，詳細，設定など複数の子ページを持たせることが考えられます．以下は，その一例です．

```tsx
// 例: app/router.tsx の一部
const ProfileRoute = ProfileImport.update({
	id: '/profile',
	path: '/profile',
	getParentRoute: () => rootRoute,
	component: ProfileLayout,
} as any)

const ProfileDetailsRoute = ProfileDetailsImport.update({
	id: '/profile/details',
	path: '/details',
	getParentRoute: () => ProfileRoute,
	component: ProfileDetails,
} as any)

const ProfileSettingsRoute = ProfileSettingsImport.update({
	id: '/profile/settings',
	path: '/settings',
	getParentRoute: () => ProfileRoute,
	component: ProfileSettings,
} as any)
```

このように，親ルートに共通レイアウト（ここでは `ProfileLayout`）を設定することで，全体のデザインやエラーハンドリングを統一できます．

### 型安全なパラメータ管理

TanStack Routerの大きな魅力は，ルート定義が自動生成され，型安全にリンクやパラメータを扱える点です．たとえば，`/posts/$postId`というルートに対して，リンクを作成する際には以下のように必須パラメータがコンパイル時にチェックされます．

```tsx
// Linkコンポーネントの例
<Link to={PostsRoute} params={{ postId: '123' }}>
	投稿123を見る
</Link>
```

もし`postId`パラメータを指定しなければ，エディタ上で即座に警告が表示され，誤ったルーティング実装を防止できます．これにより，リファクタリング時のリスクも大幅に低減されます．

### エラー処理とフォールバックのカスタマイズ

各ルートごとに独自のエラーコンポーネントを定義できるため，予期せぬエラー発生時にもユーザーに適切なフィードバックを提供できます．グローバルなエラーハンドリングと，各ルート固有のエラーバウンダリを組み合わせることで，アプリ全体の堅牢性を高められます．

```tsx
// 例: app/router.tsx
const router = createTanStackRouter({
	routeTree,
	defaultPreload: 'intent',
	defaultErrorComponent: DefaultCatchBoundary,
	defaultNotFoundComponent: () => <NotFound />,
	scrollRestoration: true,
})
```

さらに，特定のルートでより詳細なエラー情報を表示するために，各ルートにカスタムのエラーコンポーネントを割り当てることも可能です．たとえば、データフェッチ中のエラーや認証エラーに対して，専用のUIを表示することができます．

### SSR（サーバーサイドレンダリング）との連携

TanStack Routerはサーバーサイドレンダリング（SSR）にも対応しており，JavaScriptがオフの場合でも動作する設計となっています．これにより，初回ロード時のパフォーマンス改善やSEO対策が期待できます．特に，TanStack Queryとの連携を通じてサーバー上でデータを先に取得し，クライアントへシームレスに受け渡すことが可能です．

```tsx
// SSR対応の例（Next.jsなどとの統合イメージ）
export async function getServerSideProps(context) {
	// サーバー上でデータを取得する処理
	const data = await fetchDataForRoute(context.params)
	return { props: { data } }
}
```

この仕組みにより，ユーザーはページロード時に必要なデータが既に用意された状態で表示され，快適な体験を享受できます．

---

## まとめ

今回の記事では，型安全なルーティングが魅力のTanStack Routerを，tanstack startを利用して簡単にセットアップする方法と，その高度な機能についてご紹介しました．以下のポイントが特に注目すべき点です．

- **型安全性**  
  自動生成されるルート定義により，リンクやパラメータの誤用が防止され，開発効率とコードの堅牢性が向上

- **ネストされたルート**  
  共通レイアウトやエラーハンドリングを効率的に実装可能

- **柔軟なエラー処理**  
  各ルートごとにカスタムのエラーコンポーネントを設定でき，ユーザーに対して適切なフィードバックを提供

- **SSR対応**  
  サーバーサイドレンダリングとの連携により，初期表示のパフォーマンス改善とSEO効果が期待できる

これらの機能を活用することで，より堅牢でメンテナブルなフロントエンドアプリケーションの構築が可能となります．