Routing
On this page

Routing

Configuring Routes

Routes are configured as the first argument to createBrowserRouter. At a minimum, you need a path and component:

import { createBrowserRouter } from "react-router";  function Root() {  return <h1>Hello world</h1>; }  const router = createBrowserRouter([  { path: "/", Component: Root }, ]); 

Here is a larger sample route config:

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, but here's a quick example of a loader.

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 <h1>{data.name}</h1>; } 

Nested Routes

Routes can be nested inside parent routes through children.

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 <Outlet/> in the parent route.

import { Outlet } from "react-router";  export default function Dashboard() {  return (  <div>  <h1>Dashboard</h1>  {/* will either be <Home> or <Settings> */}  <Outlet />  </div>  ); } 

Layout Routes

Omitting the path in a route creates new Nested Routes for its children without adding any segments to the URL.

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.

{ index: true, Component: Home } 

Index routes render into their parent's Outlet at their parent's URL (like a default child route).

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.

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.

{  path: "teams/:teamId",  loader: async ({ params }) => {  // params are available in loaders/actions  let team = await fetchTeam(params.teamId);  return { name: team.name };  },  Component: Team, } 
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:

{  path: "c/:categoryId/p/:productId"; } 

Optional Segments

You can make a route segment optional by adding a ? to the end of the segment.

{  path: ":lang?/categories"; } 

You can have optional static segments, too:

{  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.

{  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:

const { "*": splat } = params; 

Next: Route Object

Docs and examples CC 4.0
Edit