Typesafe React Navigation with Tanstack Router - Full Guide

January 07, 2025

Navigation is an essential feature of every modern web application. Unlike other frameworks that have built-in navigation, React relies on third-party libraries. For a long time, React Router has been the go-to choice, but it comes with its own set of challenges, such as frequent breaking changes and limited TypeScript support.

In this post, we’ll explore TanStack Router, a robust alternative that offers developer-friendly features, first-class TypeScript support, and a consistent API.

Let’s dive into how to use TanStack Router by building a multi-page application step by step.


Why TanStack Router?

TanStack Router comes with a host of features that make it a compelling choice:

  • File-based routing: Routes map directly to your file structure.
  • Secure URL handling: Validation ensures your app processes only valid URLs.
  • Developer-friendly: Streamlined setup and intuitive API.
  • User-friendly: Delivers a great experience for end-users.
  • TypeScript support: First-class support for type safety.
  • Consistency: A stable API compared to the breaking changes often seen in React Router.

Getting Started with TanStack Router

Setting Up the Project

To get started, install TanStack Router in your existing Vite project. If you're starting from scratch, you can use the command to scaffold a new project with everything set up:

npm create @tanstack/router@latest

If you already have a project, here’s how to install and configure it manually:

  1. Install the library:
npm install @tanstack/router @tanstack/router-devtools
  1. Add the TanStack Router plugin to your vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tanstackRouter from "@tanstack/router/vite";

export default defineConfig({
  plugins: [react(), tanstackRouter()],
});
  1. Create a routes directory and start defining your routes. The library will auto-generate routing code based on your file structure.

Core Features

1. Dynamic Route Segments

Dynamic routes allow you to handle URLs with parameters. For example, to create a route like /contact/:id, define a file named [contactId].tsx. You can then use useParams to access the route parameter:

import { useParams } from "@tanstack/router";

function ContactPage() {
  const { contactId } = useParams();
  return <div>Contact ID: {contactId}</div>;
}

2. Static and Dynamic Navigation

TanStack Router supports both static navigation with a Link component and dynamic navigation using the useNavigate hook.

  • Static Navigation:
import { Link } from "@tanstack/router";

function ContactsList() {
  return <Link to="/contact/123">Go to Contact 123</Link>;
}
  • Dynamic Navigation:
import { useNavigate } from "@tanstack/router";

function AddContact() {
  const navigate = useNavigate();
  const handleCreate = (newContactId) => {
    navigate({ to: `/contact/${newContactId}` });
  };

  return <button onClick={() => handleCreate("123")}>Create Contact</button>;
}

3. Search Parameters with Validation

TanStack Router allows you to handle search parameters securely using schemas like Zod. For example, to manage a parameter like editContactId:

import { z } from "zod";

const searchParamsSchema = z.object({
  editContactId: z.string().uuid().optional(),
});

// Validate search parameters
const { editContactId } = useSearch(searchParamsSchema);

This ensures that only valid UUIDs are processed, rejecting invalid or malformed inputs.


Conclusion

TanStack Router offers a developer-friendly and feature-rich navigation solution for React applications.

Its support for file-based routing, TypeScript, and URL validation makes it a great choice for creating scalable, user-friendly applications.

If you found this guide helpful, consider exploring the full React Query course from the same author for even more insights into modern React development.