Upgrade to Pro — share decks privately, control downloads, hide ads and more …

๐Ÿ‡ต๐Ÿ‡น JNation 2025

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →

๐Ÿ‡ต๐Ÿ‡น JNationย 2025

TanStack Router: Beyond the Basics

Modern routing isnโ€™t just about navigating between pages anymoreโ€”itโ€™s about dynamic data loading, route transitions, and user experience. Join us as we uncover the superpowers of TanStack React Router. Weโ€™ll explore features that go beyond the basics, like nested routing, type-safe loaders, and prefetching strategies. Expect a fun ride with real-world examples, tips to optimize performance, and a live demo of building a mini-dashboard app that uses all the best features of TanStack Router.

Avatar for Joana Santos

Joana Santos

May 29, 2025

Other Decks in Programming

Transcript

  1. Getting started Todayโ€™s Roadtrip Nested routes and parameters Smart Data

    Fetching Location Masking @joanamcsa ๐Ÿž Routing in modern React apps Why TanStack Router?
  2. @joanamcsa ๐Ÿž npm install @tanstack/react-router const router = createRouter({ routeTree

    }) declare module '@tanstack/react-router' { interface Register { router: typeof router } } <RouterProvider router={router} /> Getting started
  3. Nested Routes and Parameters @joanamcsa ๐Ÿž export const Route =

    createFileRoute('/cities/')({ component: RouteComponent, }); function RouteComponent() { return <div>Hello "/cities/"!</div>; } routes/cities/index.tsx
  4. Nested Routes and Parameters @joanamcsa ๐Ÿž export const Route =

    createFileRoute('/cities/$cityId')({ component: RouteComponent, }); function RouteComponent() { const { cityId } = Route.useParams(); return <div>Hello "/cities/{cityId}"!</div>; } routes/cities/$cityId.tsx
  5. Nested Routes and Parameters @joanamcsa ๐Ÿž routes/cities/$cityId.tsx export const Route

    = createFileRoute('/cities/$cityId')({ component: RouteComponent, }); function RouteComponent() { const { cityID } = Route.useParams(); return <div>Hello "/cities/{cityId}"!</div>; }
  6. Nested Routes and Parameters @joanamcsa ๐Ÿž export const Route =

    createFileRoute('/cities/')({ component: RouteComponent, }); routes/cities/index.tsx
  7. Nested Routes and Parameters @joanamcsa ๐Ÿž const CitiesSearchSchema = z.object({

    page: z.number().catch(1), }); export const Route = createFileRoute(โ€˜/cities/')({ component: RouteComponent, validateSearch: CitiesSearchSchema, }); routes/cities/index.tsx
  8. Nested Routes and Parameters @joanamcsa ๐Ÿž const CitiesSearchSchema = z.object({

    page: z.number().catch(1), }); export const Route = createFileRoute(โ€˜/cities/')({ component: RouteComponent, validateSearch: CitiesSearchSchema, }); function RouteComponent() { const { page } = Route.useSearch(); return <div>Hello from page {page}</div> } routes/cities/index.tsx
  9. Route Guards @joanamcsa ๐Ÿž export const Route = createFileRoute(โ€˜/cities/โ€˜)({ component:

    RouteComponent, beforeLoad: async () => { const city = await trpc.cityRouter.getFirstCity.query(); if (!city) { throw redirect({ to: '/' }); } }, }); routes/cities/index.tsx
  10. Smart Data Fetching @joanamcsa ๐Ÿž export const Route = createFileRoute(โ€˜/cities/')({

    component: RouteComponent, validateSearch: CitiesSearchSchema, loaderDeps: ({ search }) => search, loader: async ({ deps }) => { const { page } = deps; const city = await trpc.cityRouter.getFirstCity.query(); return { page, city }; }, }); routes/cities/index.tsx
  11. Smart Data Fetching @joanamcsa ๐Ÿž function RouteComponent() { const {

    city } = Route.useLoaderData(); return ( <div> <h1 className="text-4xl">{city?.name} - first city</h1> </div> ); } routes/cities/index.tsx
  12. Smart Data Fetching @joanamcsa ๐Ÿž export const Route = createFileRoute(โ€˜/cities/')({

    component: RouteComponent, loader: async () => { const city = await trpc.cityRouter.getFirstCity.query(); const promiseCities = trpc.cityRouter.getAll.query(); return { city, promiseCities }; }, }); routes/cities/index.tsx
  13. Smart Data Fetching @joanamcsa ๐Ÿž function RouteComponent() { const {

    city, promiseCities } = Route.useLoaderData(); return ( <div className="p-2 flex flex-col gap-2"> <p>Our first city {city?.name}</p> <Await promise={promiseCities} fallback={<div>Loading...</div>}> {(data) => ( <div> This is the count of cities: {data.length} <ul> {data.map((city) => ( <li key={city.id}>{city.name}</li> ))} </ul> </div> )} </Await> </div> ); } routes/cities/index.tsx