Skip to Content
BlogTanStack Router: A Modern and scalable routing library for React

TanStack Router: A Modern and scalable routing library for React

mount-fuji

πŸ“Έ

Pexels

Okay, here i’m once again with another topic that i’m sure you will find useful.

Recently, i’ve been working on a project that uses TanStack Router  and i’ve learned a lot about it. So, i’ve decided to write a guide about it.

In this guide, i’ll show you how to do file-based routing and see how powerful tanstack router is.

What is TanStack Router?

TanStack Router is a fully type-safe routing solution for React applications and it will make you to fall in love with routing again πŸ™ˆ. Created by Tanner Linsley (the same mind behind React Query ), it aims to solve many of the pain points developers face with traditional routing libraries.

So now you must be wondering what kind of features it has to offer.

  • 100% inferred TypeScript support
  • Typesafe navigation
  • File-based routing
  • Code based routing
  • Code splitting
  • Path and Search Parameter Schema Validation
  • Built-in Route Loaders w/ SWR Caching
  • Search Param Navigation APIs
  • Custom Search Param parser/serializer support
  • Search param middleware
  • Route matching/loading middleware

Sounds cool, right?

I know you are excited knowing more about it.

Getting Started

Okay, let’s code.

So TanStack Router provides two ways to create routes:

  • File-based routing
  • Code based routing

File-based routing is the recommended way to create routes.

Code based routing is the alternative way to create routes.

They are both great and i’ll show you how to use both of them.

File-based Routing

So, let’s start with the file-based routing.

First, install the dependencies:

npm install @tanstack/react-router @tanstack/react-router-devtools

Create the following files:

  • src/routes/__root.tsx (with two _ characters)
  • src/routes/index.tsx
  • src/routes/about.tsx
  • src/main.tsx
src/routes/__root.tsx
import { createRootRoute, Link, Outlet } from '@tanstack/react-router' import { TanStackRouterDevtools } from '@tanstack/react-router-devtools' // ROUTE export const Route = createRootRoute({ component: RootComponent, }) // COMPONENT function RootComponent() { return ( <> <div className="p-2 flex gap-2"> <Link to="/" className="[&.active]:font-bold"> Home </Link>{' '} <Link to="/about" className="[&.active]:font-bold"> About </Link> </div> <hr /> <Outlet /> <TanStackRouterDevtools /> </> ), }

Root route is the parent of all routes. It contains the common layout and components for all routes. Think of it as the Layout component of Next.js.

src/routes/index.tsx
import { createLazyFileRoute } from '@tanstack/react-router' export const Route = createLazyFileRoute('/')({ component: Index, }) function Index() { return ( <div className="p-2"> <h3>Welcome Home!</h3> </div> ) }

Here i’m using the createLazyFileRoute function to create the file based route. but you can also use the createFileRoute function. the difference between them is that createLazyFileRoute is used for lazy loading the route and createFileRoute is used for normal routes.

src/routes/about.tsx
import { createLazyFileRoute } from '@tanstack/react-router' export const Route = createLazyFileRoute('/about')({ component: About, }) function About() { return <div className="p-2">Hello from About!</div> }
src/main.tsx
import { StrictMode } from 'react' import ReactDOM from 'react-dom/client' import { RouterProvider, createRouter } from '@tanstack/react-router' // Import the generated route tree import { routeTree } from './routeTree.gen' // Create a new router instance const router = createRouter({ routeTree }) // Register the router instance for type safety declare module '@tanstack/react-router' { interface Register { router: typeof router } } // Render the app const rootElement = document.getElementById('root')! if (!rootElement.innerHTML) { const root = ReactDOM.createRoot(rootElement) root.render( <StrictMode> <RouterProvider router={router} /> </StrictMode>, ) }
πŸ’‘

When you run npm run dev/npm run build scripts, or manually running the tsr watch/tsr generate commands from your package scripts, the route tree file will be generated at src/routeTree.gen.ts.

Folder Structure

src/ β”œβ”€β”€ routes/ β”‚ β”œβ”€β”€ __root.tsx β”‚ β”œβ”€β”€ index.tsx β”‚ └── about.tsx β”œβ”€β”€ routeTree.gen.ts └── main.tsx

Okay, now you know how to create the file-based routing.

Code Based Routing

😎

Since they recommend splitting routes into separate files for better organization and performance as our application grows, i’ll show you how to do that.

It is gonna be a bit confusing, so i’ll first show you the folder structure and then i’ll write the code for each file.

Folder Structure

src/ β”œβ”€β”€ routes/ β”‚ β”œβ”€β”€ __root.tsx β”‚ β”œβ”€β”€ index.tsx β”‚ └── about.tsx β”œβ”€β”€ routeTree.gen.ts └── main.tsx

Okay, now let’s write the code for each file.

src/routes/__root.tsx
import {createRootRoute, Outlet, Link} from "@tanstack/react-router"; import { TanStackRouterDevtools } from '@tanstack/react-router-devtools' export const rootRoute = createRootRoute({ component: RootComponent, }); function RootComponent() { return ( <> <div className="p-2 flex gap-2"> <Link to="/" className="[&.active]:font-bold"> Home </Link>{' '} <Link to="/about" className="[&.active]:font-bold"> About </Link> </div> <hr /> <Outlet /> <TanStackRouterDevtools /> </> ); }
src/routes/index.tsx
import {createRoute} from "@tanstack/react-router"; import {rootRoute} from "./__root"; // ROUTE export const indexRoute = createRoute({ getParentRoute: () => rootRoute, path: "/", component: Index, }); // COMPONENT function Index() { return ( <div className="p-2 bg-green-500"> <h3>Welcome Home!</h3> </div> ); }
src/routes/about.tsx
import {createRoute} from "@tanstack/react-router"; import {rootRoute} from "./__root"; // ROUTE export const aboutRoute = createRoute({ getParentRoute: () => rootRoute, path: "/about", component: About, }); // COMPONENT function About() { return <div className="p-2">Hello from About!</div>; }
src/main.tsx
import {StrictMode} from "react"; import ReactDOM from "react-dom/client"; import { RouterProvider, createRouter, } from "@tanstack/react-router"; // ROUTES import {rootRoute} from "./routes/__root"; import {indexRoute} from "./routes/index"; import {aboutRoute} from "./routes/about"; // ROUTE TREE const routeTree = rootRoute.addChildren([ indexRoute, aboutRoute, ]); // Set up a Router instance const router = createRouter({ routeTree, scrollRestoration: true, }); // Register the router instance for type safety declare module "@tanstack/react-router" { interface Register { router: typeof router; } } // Render the app const rootElement = document.getElementById("root")!; if (!rootElement.innerHTML) { const root = ReactDOM.createRoot(rootElement); root.render( <StrictMode> <RouterProvider router={router} /> </StrictMode> ); }

Booyah πŸŽ‰, we did it man.

Now you know how to do file-based and code-based routing and what are the differences between them and why you should try it.

Conclusion

Okay, see i’m totally in love with file-based routing it has made my life so much easier in terms of organization routing and managing Search Param APIs.

Tanner Linsley ❀️ is a genius, i’m not kidding. he has made routing easier and simpler than ever.

Give it a try and you will love it too πŸ’–.

Cheers πŸ₯‚. Comment down below if you have any questions or feedback.

Comments

Leave a comment or reaction below!

Last updated on