Skip to content

React Tutorial Routing and Application Structure

Route Configuration in React Router: Routes, Index and Layouts

Lesson 105 of 156 3 min read By Deepak Paswan Updated Oct 10, 2026

Full-project lesson · needs Node.js, npm and real project files, so it does not run in the in-page playground.

This lesson shows how routes are described, in the two styles you will meet: JSX routes (declarative mode) and a route object array (data mode). Both use the same concepts.

JSX routes

You have seen this style:

App.jsx
JSX
<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
  <Route path="/contact" element={<Contact />} />
</Routes>

The ideas to know:

  • path is matched against the URL. Matching ignores trailing slashes and is case-insensitive by default.
  • element is the JSX to render when it matches.
  • Routes are matched by specificity, not only by order, so you do not need to worry much about the order of routes.
  • A route with path="*" matches anything not matched by other routes; see Not Found Pages.

Path patterns

PatternMatchesNotes
/about/aboutA static path
/products/:id/products/42:id is a dynamic segment; see Route Parameters
/files/*/files/a/b/cA splat: matches the rest of the path
/users/:id?/users and /users/7Optional segment
*everything elseUsed for “not found”

Query strings (?page=2) are not part of a path; read them with useSearchParams.

Index routes

An index route is the default child of a parent path: the one that shows when the URL is exactly the parent’s. It has no path of its own, just index:

App.jsx
JSX
<Route path="/dashboard" element={<DashboardLayout />}>
  <Route index element={<DashboardHome />} />        {/* /dashboard */}
  <Route path="settings" element={<Settings />} />   {/* /dashboard/settings */}
</Route>

Nesting is covered in Nested Routes.

Route objects (data mode)

The second style describes routes as plain objects in an array, and gives them to createBrowserRouter. It looks like this in src/main.jsx:

src/main.jsx
JSX
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { createBrowserRouter, RouterProvider, Link } from 'react-router'
import './index.css'

function Home() {
  return (
    <div>
      <h1>Welcome to the shop</h1>
      <nav>
        <Link to="/">Home</Link> | <Link to="/products">Products</Link>
      </nav>
    </div>
  )
}

function Products() {
  return (
    <div>
      <h1>Product list</h1>
      <Link to="/">Back home</Link>
    </div>
  )
}

const router = createBrowserRouter([
  { path: '/', Component: Home },
  { path: '/products', Component: Products },
])

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <RouterProvider router={router} />
  </StrictMode>,
)

(Built with Vite and tested in a browser, including opening /products directly.)

Differences from JSX routes:

  • createBrowserRouter([...]) creates the router outside React, once.
  • <RouterProvider router={router} /> replaces BrowserRouter + Routes.
  • A route object uses Component (the component itself) or element (a JSX element). Both work: { path: '/', Component: Home } is the same as { path: '/', element: <Home /> }.
  • Children go in a children array.

Why use the object form? It enables route-level features such as loader (fetch data before rendering), action (handle form submissions), errorElement and lazy (load code on demand). You will use them in Route Loaders and Lazy Routes.

Which mode should I choose?

  • Start with declarative (BrowserRouter) for small apps and learning.
  • Choose data mode when routes need to load data, handle forms or lazy-load code. Note that you must choose one at the top of your app, because BrowserRouter and RouterProvider are alternatives.
  • For a server-rendered or file-based setup, consider framework mode or a different framework.

Hash and memory routers

Two other routers exist for special cases:

  • HashRouter keeps the route after a # (/#/about). Use it only when you cannot make the server return index.html.
  • MemoryRouter keeps the location in memory, with no address bar. It is perfect for tests and non-browser environments; see Basic Testing Concepts.

Key points

  • A route pairs a path with an element (or Component). Use index for the default child, :name for parameters and * for splats.
  • JSX routes and route objects describe the same thing.
  • Use route objects with createBrowserRouter when you want loaders, actions and lazy loading.