Capítulo 2 de 24

Chapter 2: Quickstart (Code-Based Routing)

Core Idea

The code-based counterpart to the file-based quickstart: the exact same two-page app (Home/About), but every route is declared as a JavaScript object with createRoute and assembled into a tree by hand with addChildren. It shows the alternative to file-based routing when a team prefers routes defined entirely in code.

Setup

  • Routing style: code-based (no src/routes folder, no @tanstack/router-plugin, no code generation)
  • Key dependencies: @tanstack/react-router, @tanstack/react-router-devtools, React 19, Tailwind v4. Notably absent compared to the file-based version: @tanstack/router-plugin, zod, redaxios.
  • Structure: everything lives in a single src/main.tsx. A rootRoute is created with createRootRoute, child routes (indexRoute, aboutRoute) are created with createRoute and given getParentRoute, then combined into routeTree with rootRoute.addChildren([...]).

Code Example

// src/main.tsx
const rootRoute = createRootRoute({
  component: () => (
    <>
      <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 />
    </>
  ),
})

const indexRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/',
  component: function Index() {
    return <div className="p-2"><h3>Welcome Home!</h3></div>
  },
})

const aboutRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/about',
  component: function About() {
    return <div className="p-2">Hello from About!</div>
  },
})

const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])

const router = createRouter({ routeTree, defaultPreload: 'intent', scrollRestoration: true })
  • What it demonstrates: building a routeTree manually with createRootRoute + createRoute + addChildren, no filesystem convention involved. Link still gets full path type safety because routeTree is a typed value passed straight into createRouter.

Key Takeaways

  1. Code-based routing keeps the whole route tree visible in one place, useful for small apps or when a team wants explicit control without a build-time codegen step.
  2. Every child route needs getParentRoute: () => parentRoute to attach into the tree; nesting is expressed by nesting these calls, unlike file-based routing where nesting comes from filenames.
  3. createRoute and createFileRoute share nearly identical options (component, loader, validateSearch, etc.); switching between the two styles is mostly a matter of where the object is created, not what it can do.

Connects To

  • ch001-quickstart-file-based: identical UI and behavior, but routes come from src/routes/*.tsx files and a generated routeTree.gen.ts instead of hand-written addChildren calls.
  • ch004-basic (code-based): a larger code-based example showing lazy-loaded route components (.lazy()) and nested pathless layouts built the same manual way.