Directory-Based Routing Basics

Lesson 1 — Folders, route files, and nesting

TanStack Router supports directory-based routing just like Next.js. A folder is a path segment, and route.tsx defines the route component. The mental model carries over — you just need to know which files do what.

From Next.js to TanStack Router

In Next.js App Router:

app/ ├── home/ │ ├── page.tsx → /home │ └── [id]/ │ └── page.tsx → /home/123 └── layout.tsx → wraps everything

In TanStack Router (directory-based):

routes/ ├── home/ │ └── route.tsx → /home (layout route) ├── home/ │ └── $postId/ │ └── route.tsx → /home/$postId └── __root.tsx → wraps everything
⚡ Key insight route.tsx is like Next.js page.tsx + layout.tsx combined. If a folder has route.tsx, it becomes a route in the tree. Child folders in that directory become nested routes.

Route Files: What Goes Where

File/FolderPurpose
__root.tsxRoot layout — wraps entire app
route.tsxRoute component — defines a layout route
index.tsxIndex route — renders at parent path (e.g., /home from home/index.tsx)

Layout Routes vs Index Routes

Layout route (route.tsx): Renders children via <Outlet />

// routes/settings/route.tsx
import { Outlet, createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/settings')({
  component: SettingsLayout,
})

function SettingsLayout() {
  return (
    <div>
      <h1>Settings</h1>
      <Outlet />  {/* child routes render here */}
    </div>
  )
}

Index route (index.tsx): Renders at the parent path, no children

// routes/settings/index.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/settings/')({
  component: SettingsHome,
})

function SettingsHome() {
  return <div>Choose a setting from the sidebar</div>
}

The <Outlet> = Where Children Render

In Next.js, layouts get {children} automatically. In TanStack Router, you explicitly choose where child routes render using <Outlet />.

When you visit /settings/account:

routes/ ├── settings/ │ ├── route.tsx → layout with <Outlet /> │ └── account/ │ └── route.tsx → child component

TanStack Router renders both components, plugging the child into the outlet:

URLComponent Tree
/settings<SettingsLayout>
/settings/account<SettingsLayout><AccountSettings /></SettingsLayout>

Building a Mobile-Like App

Let's model a typical mobile social app: tabs at the bottom, detail screens, and settings.

routes/ ├── __root.tsx → always rendered ├── _app/ │ ├── route.tsx → pathless layout (tabs) │ ├── index.tsx → / (home feed) │ ├── explore/ │ │ └── route.tsx → /explore │ └── profile/ │ └── route.tsx → /profile ├── posts/ │ ├── $postId/ │ │ ├── route.tsx → /posts/42 │ │ └── comments/ │ │ └── route.tsx → /posts/42/comments └── settings/ ├── route.tsx → /settings (layout) └── account/ └── route.tsx → /settings/account
⚡ The underscore prefix _app/ is a pathless route. It wraps children but does not add a segment to the URL. The URL is /explore, not /_app/explore. We'll cover this fully in Lesson 2.

How it composes

URLRendered Tree
/<Root><AppLayout><HomeFeed /></AppLayout></Root>
/explore<Root><AppLayout><Explore /></AppLayout></Root>
/posts/42<Root><AppLayout><PostDetail postId="42" /></AppLayout></Root>
/posts/42/comments<Root><AppLayout><PostDetail postId="42"><Comments /></PostDetail></AppLayout></Root>

Notice how /posts/42 renders <PostDetail /> inside the app layout. But /posts/42/comments renders <Comments /> inside <PostDetail /> — which is itself inside <AppLayout />. Three levels of nesting.

Quick Quiz

1. What URL does routes/shop/items/$itemId/route.tsx match?

/shop
/shop/items/42
/shop/items/$itemId
Each folder becomes a path segment. $itemId is the dynamic segment. The file maps to /shop/items/:itemId.

2. If settings/route.tsx has no <Outlet />, what happens at /settings/account?

Only <AccountSettings /> renders
<SettingsLayout /> renders, but child content is lost
404 error
TanStack still matches and renders settings/route.tsx, but without an <Outlet /> there is nowhere to place the child. The child simply doesn't appear.

3. What's the difference between route.tsx and index.tsx?

No difference — they're the same
route.tsx is a layout, index.tsx renders at parent path
index.tsx wraps children, route.tsx doesn't
route.tsx creates a layout route that can have children (uses <Outlet />). index.tsx is a terminal route that renders at the parent path (e.g., /settings from settings/index.tsx).

4. Which folder structure matches /blog/2024?

routes/blog.tsx and routes/blog.2024.tsx
routes/blog/route.tsx and routes/blog/2024/route.tsx
routes/blog.tsx and routes/2024.tsx
Each folder becomes a path segment. blog/2024/route.tsx creates /blog/2024.

5. What does __root.tsx do?

Defines the home page at /
Wraps the entire app with a layout
Creates a pathless route for authentication
__root.tsx is the root layout — it's always rendered and wraps the entire application.

6. If you have posts/route.tsx and posts/index.tsx, what renders at /posts?

Only posts/route.tsx
Only posts/index.tsx
Both — layout wraps index content
Both render! posts/route.tsx is the layout (with <Outlet />), and posts/index.tsx content renders inside it.

7. How many path segments does routes/admin/users/edit/route.tsx create?

Two segments
Three segments
Four segments
Each folder is a segment: admin, users, edit — that's three segments, plus the route.tsx creates the route at /admin/users/edit.

8. What's the purpose of <Outlet /> in TanStack Router?

To define the route path
To render child routes
To create navigation links
<Outlet /> is where child routes render. Without it, child components won't appear in the layout.

9. Which file is required for a folder to become a route?

index.tsx
route.tsx
Both are required
route.tsx defines the route component. A folder without route.tsx won't create a route (unless it has index.tsx and a parent with route.tsx).

10. In TanStack Router, how do you access route params like $postId?

Via useParams() hook
Via route's params in loader/component
Via route.params global object
Params are accessible through the route's context in loaders and components, typically via hooks like useParams() or directly in route configuration.
Lesson 2: Pathless Routes & Groups →
🎓 Stuck on something?
Ask your teacher anything — route matching edge cases, why your tree isn't rendering as expected, or how this maps to your specific app.