Skip to content
Dashboard

TanStack Router vs React Router

Copy link to headingTwo routing philosophies

Copy link to headingPick the React Router mode first

Copy link to headingType safety with a worked example

import { z } from 'zod'
import { createFileRoute } from '@tanstack/react-router'
const dashboardSearchSchema = z.object({
filter: z.string().catch(''),
page: z.number().catch(1),
sort: z.enum(['newest', 'oldest', 'priority']).catch('newest'),
})
export const Route = createFileRoute('/dashboard')({
validateSearch: (search) => dashboardSearchSchema.parse(search),
loaderDeps: ({ search: { filter, page, sort } }) => ({ filter, page, sort }),
loader: ({ deps: { filter, page, sort } }) =>
fetchIssues({ filter, page, sort }),
component: DashboardRoute,
})
function DashboardRoute() {
const { filter, page, sort } = Route.useSearch()
const issues = Route.useLoaderData()
return <IssueList filter={filter} page={page} sort={sort} issues={issues} />
}

app/routes/dashboard.tsx
import type { Route } from './+types/dashboard'
import { Form } from 'react-router'
import { fetchIssues, updateIssue } from '../lib/issues'
export async function loader({ request }: Route.LoaderArgs) {
const url = new URL(request.url)
const filter = url.searchParams.get('filter') ?? ''
const page = Number(url.searchParams.get('page') ?? '1')
const sort = url.searchParams.get('sort') ?? 'newest'
const issues = await fetchIssues({ filter, page, sort })
return { filter, page, sort, issues }
}
export async function action({ request }: Route.ActionArgs) {
const formData = await request.formData()
const id = String(formData.get('id'))
return updateIssue(id, { resolved: true })
}
export default function Dashboard({ loaderData }: Route.ComponentProps) {
const { filter, page, sort, issues } = loaderData
return (
<Form method="post">
<IssueList filter={filter} page={page} sort={sort} issues={issues} />
</Form>
)
}

Copy link to headingRoute definition at scale

Copy link to headingData loading and mutations

Copy link to headingWhat each router library is best at

Copy link to headingMigration in both directions

Copy link to headingDeployment on Vercel is the same

Copy link to headingA short decision checklist

Copy link to headingFrequently asked questions

Ready to deploy?