---
title: Routing
order: 2
---
# Routing
[MODES: data]
## Configuring Routes
Routes are configured as the first argument to `createBrowserRouter`. At a minimum, you need a path and component:
```tsx
import { createBrowserRouter } from "react-router";
function Root() {
return
Hello world
;
}
const router = createBrowserRouter([
{ path: "/", Component: Root },
]);
```
Here is a larger sample route config:
```ts filename=app/routes.ts
createBrowserRouter([
{
path: "/",
Component: Root,
children: [
{ index: true, Component: Home },
{ path: "about", Component: About },
{
path: "auth",
Component: AuthLayout,
children: [
{ path: "login", Component: Login },
{ path: "register", Component: Register },
],
},
{
path: "concerts",
children: [
{ index: true, Component: ConcertsHome },
{ path: ":city", Component: ConcertsCity },
{ path: "trending", Component: ConcertsTrending },
],
},
],
},
]);
```
## Route Objects
Route objects define the behavior of a route beyond just the path and component, like data loading and actions. We'll go into more detail in the [Route Object guide](./route-object), but here's a quick example of a loader.
```tsx filename=app/team.tsx
import {
createBrowserRouter,
useLoaderData,
} from "react-router";
createBrowserRouter([
{
path: "/teams/:teamId",
loader: async ({ params }) => {
let team = await fetchTeam(params.teamId);
return { name: team.name };
},
Component: Team,
},
]);
function Team() {
let data = useLoaderData();
return {data.name}
;
}
```
## Nested Routes
Routes can be nested inside parent routes through `children`.
```ts filename=app/routes.ts
createBrowserRouter([
{
path: "/dashboard",
Component: Dashboard,
children: [
{ index: true, Component: Home },
{ path: "settings", Component: Settings },
],
},
]);
```
The path of the parent is automatically included in the child, so this config creates both `"/dashboard"` and `"/dashboard/settings"` URLs.
Child routes are rendered through the `` in the parent route.
```tsx filename=app/dashboard.tsx
import { Outlet } from "react-router";
export default function Dashboard() {
return (
Dashboard
{/* will either be or */}
);
}
```
## Layout Routes
Omitting the `path` in a route creates new [Nested Routes](#nested-routes) for its children without adding any segments to the URL.
```tsx lines=[3,16]
createBrowserRouter([
{
// no path on this parent route, just the component
Component: MarketingLayout,
children: [
{ index: true, Component: Home },
{ path: "contact", Component: Contact },
],
},
{
path: "projects",
children: [
{ index: true, Component: ProjectsHome },
{
// again, no path, just a component for the layout
Component: ProjectLayout,
children: [
{ path: ":pid", Component: Project },
{ path: ":pid/edit", Component: EditProject },
],
},
],
},
]);
```
Note that:
- `Home` and `Contact` will be rendered into the `MarketingLayout` outlet
- `Project` and `EditProject` will be rendered into the `ProjectLayout` outlet while `ProjectsHome` will not.
## Index Routes
Index routes are defined by setting `index: true` on a route object without a path.
```ts
{ index: true, Component: Home }
```
Index routes render into their parent's [Outlet][outlet] at their parent's URL (like a default child route).
```ts lines=[4,5,10,11]
import { createBrowserRouter } from "react-router";
createBrowserRouter([
// renders at "/"
{ index: true, Component: Home },
{
Component: Dashboard,
path: "/dashboard",
children: [
// renders at "/dashboard"
{ index: true, Component: DashboardHome },
{ path: "settings", Component: DashboardSettings },
],
},
]);
```
Note that index routes can't have children.
## Prefix Route
A route with just a path and no component creates a group of routes with a path prefix.
```tsx lines=[3]
createBrowserRouter([
{
// no component, just a path
path: "/projects",
children: [
{ index: true, Component: ProjectsHome },
{ path: ":pid", Component: Project },
{ path: ":pid/edit", Component: EditProject },
],
},
]);
```
This creates the routes `/projects`, `/projects/:pid`, and `/projects/:pid/edit` without introducing a layout component.
## Dynamic Segments
If a path segment starts with `:` then it becomes a "dynamic segment". When the route matches the URL, the dynamic segment will be parsed from the URL and provided as `params` to other router APIs.
```ts lines=[2]
{
path: "teams/:teamId",
loader: async ({ params }) => {
// params are available in loaders/actions
let team = await fetchTeam(params.teamId);
return { name: team.name };
},
Component: Team,
}
```
```tsx
import { useParams } from "react-router";
function Team() {
// params are available in components through useParams
let params = useParams();
// ...
}
```
You can have multiple dynamic segments in one route path:
```ts
{
path: "c/:categoryId/p/:productId";
}
```
## Optional Segments
You can make a route segment optional by adding a `?` to the end of the segment.
```ts
{
path: ":lang?/categories";
}
```
You can have optional static segments, too:
```ts
{
path: "users/:userId/edit?";
}
```
## Splats
Also known as "catchall" and "star" segments. If a route path pattern ends with `/*` then it will match any characters following the `/`, including other `/` characters.
```ts
{
path: "files/*";
loader: async ({ params }) => {
params["*"]; // will contain the remaining URL after files/
};
}
```
You can destructure the `*`, you just have to assign it a new name. A common name is `splat`:
```tsx
const { "*": splat } = params;
```
---
Next: [Route Object](./route-object)
[outlet]: https://api.reactrouter.com/v7/functions/react_router.Outlet.html