--- id: react-tanstack-router-patterns title: TanStack Router — Type-safe / loader / search params category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [react, router, tanstack-router, vibe-coding] tech_stack: { language: "TS / React", applicable_to: ["Frontend"] } applied_in: [] aliases: [TanStack Router, file-based routing, type-safe params, loader, search validation] --- # TanStack Router > Type-safe React router. **Search params validation, file-based routing, loader, suspense** 일급. React Router 의 type-safe 버전 + Next 의 file-based. ## 📖 핵심 개념 - File-based: `routes/*.tsx` → 자동 tree. - Type-safe link: `` 컴파일 검증. - Search params: zod 같은 schema. - Loader: 라우트 진입 전 데이터 fetch. ## 💻 코드 패턴 ### Setup ```bash yarn add @tanstack/react-router @tanstack/router-plugin ``` ```ts // vite.config.ts import { TanStackRouterVite } from '@tanstack/router-plugin/vite'; plugins: [TanStackRouterVite()]; ``` ### Route 정의 (file-based) ```tsx // src/routes/__root.tsx import { Outlet, createRootRoute } from '@tanstack/react-router'; export const Route = createRootRoute({ component: () => }); // src/routes/users.$id.tsx import { createFileRoute } from '@tanstack/react-router'; import { z } from 'zod'; export const Route = createFileRoute('/users/$id')({ params: { parse: (p) => ({ id: z.string().uuid().parse(p.id) }) }, validateSearch: z.object({ tab: z.enum(['profile', 'orders']).default('profile') }), loader: async ({ params }) => api.user.get(params.id), component: UserPage, }); function UserPage() { const { id } = Route.useParams(); // typed const { tab } = Route.useSearch(); // typed const user = Route.useLoaderData(); // typed return

{user.name}

; } ``` ### Link (type-safe) ```tsx import { Link } from '@tanstack/react-router'; Profile // 잘못된 path / params 컴파일 에러 ``` ### Navigate (programmatic) ```tsx const navigate = Route.useNavigate(); navigate({ to: '/users/$id', params: { id: '42' } }); // 또는 search 만 update navigate({ search: (prev) => ({ ...prev, tab: 'orders' }) }); ``` ### Loader + Suspense ```tsx export const Route = createFileRoute('/posts')({ loader: async () => api.posts.list(), pendingComponent: () => , errorComponent: ({ error }) => , component: PostsPage, }); function PostsPage() { const posts = Route.useLoaderData(); return ... } ``` ### TanStack Query 통합 (loader 안) ```ts import { queryOptions } from '@tanstack/react-query'; const userQuery = (id: string) => queryOptions({ queryKey: ['user', id], queryFn: () => api.user.get(id), }); export const Route = createFileRoute('/users/$id')({ loader: ({ context, params }) => context.queryClient.ensureQueryData(userQuery(params.id)), component: UserPage, }); function UserPage() { const { id } = Route.useParams(); const { data } = useSuspenseQuery(userQuery(id)); return

{data.name}

; } ``` ### Search params (typed link) ```tsx Posts const { q, page } = Route.useSearch(); ``` URL: `/posts?q=react&page=2`. ### Nested layout ```tsx // routes/_app.tsx — layout export const Route = createFileRoute('/_app')({ component: () => (
), }); // routes/_app.users.tsx — _app layout 안 export const Route = createFileRoute('/_app/users')({...}); ``` ### Auth (beforeLoad) ```ts export const Route = createFileRoute('/admin')({ beforeLoad: async ({ context }) => { if (!context.auth.user) throw redirect({ to: '/login' }); }, }); ``` ### Devtools ```tsx import { TanStackRouterDevtools } from '@tanstack/router-devtools'; ``` ## 🤔 의사결정 기준 | 상황 | 추천 | |---|---| | Type-safe critical | TanStack Router | | Next.js | Next App Router (자체) | | 단순 SPA | React Router 6 | | 거대 monorepo + 강 types | TanStack Router | | File-based + SSR | Next / Remix | | 빠른 prototype | React Router | ## ❌ 안티패턴 - **String path concat**: type 안전 X. params object. - **Search 검증 없음**: 잘못된 URL 이 crash. - **Loader 안에 mutation**: 의도와 다름. action 으로. - **Route 별 `useParams()` 매번 type 인자**: factory 활용. - **beforeLoad 무거운 작업**: 라우트 진입 느림. - **404 / pendingComponent 없음**: 빈 화면. ## 🤖 LLM 활용 힌트 - File-based + zod search/params + loader + TQ 통합 4종. - Vite plugin 자동 generate. - Devtools 필수 (개발). ## 🔗 관련 문서 - [[React_TanStack_Query_Advanced]] - [[React_Router_Patterns]] - [[React_Suspense_for_Data]]