

Welcome to React Router
========================


  [### Ready for Data?

 v6.4 brings over all the things we've learned about keeping your data in sync with your UI from Remix to React Router. Developing web apps has never been this fun. Get started with data here.](https://reactrouterdotcom.fly.dev/docs/en/dev/getting-started/data)   [### New to React Router?

 We suggest you start with the tutorial. It's got everything you need to know to get up and running in React Router quickly.](https://reactrouterdotcom.fly.dev/docs/en/dev/getting-started/tutorial)   [### Familiar with React Router?

 We introduced several new features and exciting changes in version 6. Learn all about them in this quick overview of the features that make v6 special.](https://reactrouterdotcom.fly.dev/docs/en/dev/getting-started/overview)   [### Frequently Asked Questions

 Running into a problem? Chances are, you're not the first! Explore some of the questions that people commonly have about React Router v6.](https://reactrouterdotcom.fly.dev/docs/en/dev/getting-started/faq)  
Previous Versions
------------------


* [React Router v4/5 docs](https://v5.reactrouter.com)
* [React Router v3 docs](https://github.com/remix-run/react-router/tree/v3.2.6/docs)



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6>

Feature Overview
=================



Client Side Routing
--------------------


React Router enables "client side routing".


In traditional websites, the browser requests a document from a web server, downloads and evaluates CSS and JavaScript assets, and renders the HTML sent from the server. When the user clicks a link, it starts the process all over again for a new page.


Client side routing allows your app to update the URL from a link click without making another request for another document from the server. Instead, your app can immediately render some new UI and make data requests with `fetch` to update the page with new information.


This enables faster user experiences because the browser doesn't need to request an entirely new document or re-evaluate CSS and JavaScript assets for the next page. It also enables more dynamic user experiences with things like animation.


Client side routing is enabled by creating a `Router` and linking/submitting to pages with `Link` and `<Form>`:



```
import React from "react";
import { createRoot } from "react-dom/client";
import {
  createBrowserRouter,
  RouterProvider,
  Route,
  Link,
} from "react-router-dom";

const router = createBrowserRouter([
  {
    path: "/",
    element: (
      <div>
        <h1>Hello World</h1>
        <Link to="about">About Us</Link>
      </div>
    ),
  },
  {
    path: "about",
    element: <div>About</div>,
  },
]);

createRoot(document.getElementById("root")).render(
  <RouterProvider router={router} />
);

```


Nested Routes
--------------


Nested Routing is the general idea of coupling segments of the URL to component hierarchy and data. React Router's nested routes were inspired by the routing system in Ember.js circa 2014. The Ember team realized that in nearly every case, segments of the URL determine:


* The layouts to render on the page
* The data dependencies of those layouts


React Router embraces this convention with APIs for creating nested layouts coupled to URL segments and data.



```
// Configure nested routes with JSX
createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<Root />}>
      <Route path="contact" element={<Contact />} />
      <Route
        path="dashboard"
        element={<Dashboard />}
        loader={({ request }) =>
          fetch("/api/dashboard.json", {
            signal: request.signal,
          })
        }
      />
      <Route element={<AuthLayout />}>
        <Route
          path="login"
          element={<Login />}
          loader={redirectIfUser}
        />
        <Route path="logout" />
      </Route>
    </Route>
  )
);

// Or use plain objects
createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        path: "contact",
        element: <Contact />,
      },
      {
        path: "dashboard",
        element: <Dashboard />,
        loader: ({ request }) =>
          fetch("/api/dashboard.json", {
            signal: request.signal,
          }),
      },
      {
        element: <AuthLayout />,
        children: [
          {
            path: "login",
            element: <Login />,
            loader: redirectIfUser,
          },
          {
            path: "logout",
            action: logoutUser,
          },
        ],
      },
    ],
  },
]);

```

This [visualization](https://remix.run/_docs/routing) might be helpful.



Dynamic Segments
-----------------


Segments of the URL can be dynamic placeholders that are parsed and provided to various apis.



```
<Route path="projects/:projectId/tasks/:taskId" />

```

The two segments with `:` are dynamic, and provided to the following APIs:



```
// If the current location is /projects/abc/tasks/3
<Route
  // sent to loaders
  loader={({ params }) => {
    params.projectId; // abc
    params.taskId; // 3
  }}
  // and actions
  action={({ params }) => {
    params.projectId; // abc
    params.taskId; // 3
  }}
  element={<Task />}
/>;

function Task() {
  // returned from `useParams`
  const params = useParams();
  params.projectId; // abc
  params.taskId; // 3
}

function Random() {
  const match = useMatch("/projects/:projectId/tasks/3");
  match.params.projectId; // abc
  match.params.taskId; // 3
}

```

See:


* [`<Route path>`](../route/route#path)
* [`<Route loader>`](../route/loader)
* [`<Route action>`](../route/action)
* [`useParams`](../hooks/use-params)
* [`useMatch`](../hooks/use-match)



Ranked Route Matching
----------------------


When matching URLs to routes, React Router will rank the routes according the number of segments, static segments, dynamic segments, splats, etc. and pick the *most specific* match.


For example, consider these two routes:



```
<Route path="/teams/:teamId" />
<Route path="/teams/new" />

```

Now consider the URL is <http://example.com/teams/new>.


Even though both routes technically match the URL (`new` could be the `:teamId`), you intuitively know that we want the second route (`/teams/new`) to be picked. React Router's matching algorithm knows that, too.


With ranked routes, you don't have to worry about route ordering.



Active Links
-------------


Most web apps have persistent navigation sections at the top of the UI, the sidebar, and often multiple levels. Styling the active navigation items so the user knows where they are (`isActive`) or where they're going (`isPending`) in the app is done easily with `<NavLink>`.



```
<NavLink
  style={({ isActive, isPending }) => {
    return {
      color: isActive ? "red" : "inherit",
    };
  }}
  className={({ isActive, isPending }) => {
    return isActive ? "active" : isPending ? "pending" : "";
  }}
/>

```

You can also [`useMatch`](../hooks/use-match) for any other "active" indication outside of links.



```
function SomeComp() {
  const match = useMatch("/messages");
  return <li className={Boolean(match) ? "active" : ""} />;
}

```

See:


* [`NavLink`](../components/nav-link)
* [`useMatch`](../hooks/use-match)



Relative Links
---------------


Like HTML `<a href>`, `<Link to>` and `<NavLink to>` can take relative paths, with enhanced behavior with nested routes.


Given the following route config:



```
<Route path="home" element={<Home />}>
  <Route path="project/:projectId" element={<Project />}>
    <Route path=":taskId" element={<Task />} />
  </Route>
</Route>

```

Consider the url <https://example.com/home/project/123>, which renders the following route component hierarchy:



```
<Home>
  <Project />
</Home>

```

If `<Project />` renders the following links, the hrefs of the links will resolve like so:




| In `<Project>` @ `/home/project/123` | Resolved `<a href>` |
| --- | --- |
| `<Link to="abc">` | `/home/projects/123/abc` |
| `<Link to=".">` | `/home/projects/123` |
| `<Link to="..">` | `/home` |
| `<Link to=".." relative="path">` | `/home/projects` |


Note that the first `..` removes both segments of the `project/:projectId` route. By default, the `..` in relative links traverse the route hierarchy, not the URL segments. Adding `relative="path"` in the next example allows you to traverse the path segments instead.


Relative links are always relative to the route path they are *rendered in*, not to the full URL. That means if the user navigates deeper with `<Link to="abc">` to `<Task />` at the URL `/home/projects/123/abc`, the hrefs in `<Project>` will not change (contrary to plain `<a href>`, a common problem with client side routers).



Data Loading
-------------


Because URL segments usually map to your app's persistent data, React Router provides conventional data loading hooks to initiate data loading during a navigation. Combined with nested routes, all of the data for multiple layouts at a specific URL can be loaded in parallel.



```
<Route
  path="/"
  loader={async ({ request }) => {
    // loaders can be async functions
    const res = await fetch("/api/user.json", {
      signal: request.signal,
    });
    const user = await res.json();
    return user;
  }}
  element={<Root />}
>
  <Route
    path=":teamId"
    // loaders understand Fetch Responses and will automatically
    // unwrap the res.json(), so you can simply return a fetch
    loader={({ params }) => {
      return fetch(`/api/teams/${params.teamId}`);
    }}
    element={<Team />}
  >
    <Route
      path=":gameId"
      loader={({ params }) => {
        // of course you can use any data store
        return fakeSdk.getTeam(params.gameId);
      }}
      element={<Game />}
    />
  </Route>
</Route>

```

Data is made available to your components through `useLoaderData`.



```
function Root() {
  const user = useLoaderData();
  // data from <Route path="/">
}

function Team() {
  const team = useLoaderData();
  // data from <Route path=":teamId">
}

function Game() {
  const game = useLoaderData();
  // data from <Route path=":gameId">
}

```

When the user visits or clicks links to <https://example.com/real-salt-lake/45face3>, all three route loaders will be called and loaded in parallel, before the UI for that URL renders.



Redirects
----------


While loading or changing data, it's common to [redirect](../fetch/redirect) the user to a different route.



```
<Route
  path="dashboard"
  loader={async () => {
    const user = await fake.getUser();
    if (!user) {
      // if you know you can't render the route, you can
      // throw a redirect to stop executing code here,
      // sending the user to a new route
      throw redirect("/login");
    }

    // otherwise continue
    const stats = await fake.getDashboardStats();
    return { user, stats };
  }}
/>

```


```
<Route
  path="project/new"
  action={async ({ request }) => {
    const data = await request.formData();
    const newProject = await createProject(data);
    // it's common to redirect after actions complete,
    // sending the user to the new record
    return redirect(`/projects/${newProject.id}`);
  }}
/>

```

See:


* [`redirect`](../fetch/redirect)
* [Throwing in Loaders](../route/loader#throwing-in-loaders)
* [`useNavigate`](../hooks/use-navigate)



Pending Navigation UI
----------------------


When users navigate around the app, the data for the next page is loaded before the page is rendered. It's important to provide user feedback during this time so the app doesn't feel like it's unresponsive.



```
function Root() {
  const navigation = useNavigation();
  return (
    <div>
      {navigation.state === "loading" && <GlobalSpinner />}
      <FakeSidebar />
      <Outlet />
      <FakeFooter />
    </div>
  );
}

```

See:


* [`useNavigation`](../hooks/use-navigation)



Skeleton UI with `<Suspense>`
------------------------------


Instead of waiting for the data for the next page, you can [`defer`](../utils/defer) data so the UI flips over to the next screen with placeholder UI immediately while the data loads.



```
<Route
  path="issue/:issueId"
  element={<Issue />}
  loader={async ({ params }) => {
    // these are promises, but *not* awaited
    const comments = fake.getIssueComments(params.issueId);
    const history = fake.getIssueHistory(params.issueId);
    // the issue, however, *is* awaited
    const issue = await fake.getIssue(params.issueId);

    // defer enables suspense for the un-awaited promises
    return defer({ issue, comments, history });
  }}
/>;

function Issue() {
  const { issue, history, comments } = useLoaderData();
  return (
    <div>
      <IssueDescription issue={issue} />

      {/* Suspense provides the placeholder fallback */}
      <Suspense fallback={<IssueHistorySkeleton />}>
        {/* Await manages the deferred data (promise) */}
        <Await resolve={history}>
          {/* this calls back when the data is resolved */}
          {(resolvedHistory) => (
            <IssueHistory history={resolvedHistory} />
          )}
        </Await>
      </Suspense>

      <Suspense fallback={<IssueCommentsSkeleton />}>
        <Await resolve={comments}>
          {/* ... or you can use hooks to access the data */}
          <IssueComments />
        </Await>
      </Suspense>
    </div>
  );
}

function IssueComments() {
  const comments = useAsyncValue();
  return <div>{/* ... */}</div>;
}

```

See


* [Deferred Data Guide](../guides/deferred)
* [`defer`](../utils/defer)
* [`Await`](../components/await)
* [`useAsyncValue`](../hooks/use-async-value)



Data Mutations
---------------


HTML forms are navigation events, just like links. React Router supports HTML form workflows with client side routing.


When a form is submitted, the normal browser navigation event is prevented and a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request), with a body containing the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) of the submission, is created. This request is sent to the `<Route action>` that matches the form's `<Form action>`.


Form elements's `name` prop are submitted to the action:



```
<Form action="/project/new">
  <label>
    Project title
    <br />
    <input type="text" name="title" />
  </label>

  <label>
    Target Finish Date
    <br />
    <input type="date" name="due" />
  </label>
</Form>

```

The normal HTML document request is prevented and sent to the matching route's action (`<Route path>` that matches the `<form action>`), including the `request.formData`.



```
<Route
  path="project/new"
  action={async ({ request }) => {
    const formData = await request.formData();
    const newProject = await createProject({
      title: formData.get("title"),
      due: formData.get("due"),
    });
    return redirect(`/projects/${newProject.id}`);
  }}
/>

```


Data Revalidation
------------------


Decades old web conventions indicate that when a form is posted to the server, data is changing and a new page is rendered. That convention is followed in React Router's HTML-based data mutation APIs.


After route actions are called, the loaders for all of the data on the page is called again to ensure the UI stays up-to-date with the data automatically. No cache keys to expire, no context providers to reload.


See:


* [Tutorial "Creating Contacts"](tutorial#creating-contacts)



Busy Indicators
----------------


When forms are being submitted to route actions, you have access to the navigation state to display busy indicators, disable fieldsets, etc.



```
function NewProjectForm() {
  const navigation = useNavigation();
  const busy = navigation.state === "submitting";
  return (
    <Form action="/project/new">
      <fieldset disabled={busy}>
        <label>
          Project title
          <br />
          <input type="text" name="title" />
        </label>

        <label>
          Target Finish Date
          <br />
          <input type="date" name="due" />
        </label>
      </fieldset>
      <button type="submit" disabled={busy}>
        {busy ? "Creating..." : "Create"}
      </button>
    </Form>
  );
}

```

See:


* [`useNavigation`](../hooks/use-navigation)



Optimistic UI
--------------


Knowing the [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) being sent to an [action](../route/action) is often enough to skip the busy indicators and render the UI in the next state immediately, even if your asynchronous work is still pending. This is called "optimistic UI".



```
function LikeButton({ tweet }) {
  const fetcher = useFetcher();

  // if there is `formData` then it is posting to the action
  const liked = fetcher.formData
    ? // check the formData to be optimistic
      fetcher.formData.get("liked") === "yes"
    : // if its not posting to the action, use the record's value
      tweet.liked;

  return (
    <fetcher.Form method="post" action="toggle-liked">
      <button
        type="submit"
        name="liked"
        value={liked ? "yes" : "no"}
      />
    </fetcher.Form>
  );
}

```

(Yes, HTML buttons can have a `name` and a `value`).


While it is more common to do optimistic UI with a [`fetcher`](../hooks/use-fetcher), you can do the same with a normal form using [`navigation.formData`](../hooks/use-navigation#navigationformdata).



Data Fetchers
--------------


HTML Forms are the model for mutations but they have one major limitation: you can have only one at a time because a form submission is a navigation.


Most web apps need to allow for multiple mutations to be happening at the same time, like a list of records where each can be independently deleted, marked complete, liked, etc.


[Fetchers](../hooks/use-fetcher) allow you to interact with the route [actions](../route/action) and [loaders](../route/loader) without causing a navigation in the browser, but still getting all the conventional benefits like error handling, revalidation, interruption handling, and race condition handling.


Imagine a list of tasks:



```
function Tasks() {
  const tasks = useLoaderData();
  return tasks.map((task) => (
    <div>
      <p>{task.name}</p>
      <ToggleCompleteButton task={task} />
    </div>
  ));
}

```

Each task can be marked complete independently of the rest, with its own pending state and without causing a navigation with a [fetcher](../hooks/use-fetcher):



```
function ToggleCompleteButton({ task }) {
  const fetcher = useFetcher();

  return (
    <fetcher.Form method="post" action="/toggle-complete">
      <fieldset disabled={fetcher.state !== "idle"}>
        <input type="hidden" name="id" value={task.id} />
        <input
          type="hidden"
          name="status"
          value={task.complete ? "incomplete" : "complete"}
        />
        <button type="submit">
          {task.status === "complete"
            ? "Mark Incomplete"
            : "Mark Complete"}
        </button>
      </fieldset>
    </fetcher.Form>
  );
}

```

See:


* [`useFetcher`](../hooks/use-fetcher)



Race Condition Handling
------------------------


React Router will cancel stale operations and only commit fresh data automatically.


Any time you have asynchronous UI you have the risk of race conditions: when an async operation starts after but completes before an earlier operation. The result is a user interface that shows the wrong state.


Consider a search field that updates a list as the user types:


Even though the query for `q?=ryan` went out later, it completed earlier. If not handled correctly, the results will briefly be the correct values for `?q=ryan` but then flip over the incorrect results for `?q=ry`. Throttling and debouncing are not enough (you can still interrupt the requests that get through). You need to cancellation.


If you're using React Router's data conventions you avoid this problem completely and automatically.


Not only does React Router handle race conditions for a navigation like this, it also handles it for many other cases like loading results for an autocomplete or performing multiple concurrent mutations with [`fetcher`](../hooks/use-fetcher) (and its automatic, concurrent revalidations).



Error Handling
---------------


The vast majority of your application errors are handled automatically by React Router. It will catch any errors that are thrown while:


* rendering
* loading data
* updating data


In practice, this is pretty much every error in your app except those thrown in event handlers (`<button onClick>`) or `useEffect`. React Router apps tend to have very few of either.


When an error is thrown, instead of rendering the route's [`element`](../route/route#element), the [`errorElement`](../route/error-element) is rendered.



```
<Route
  path="/"
  loader={() => {
    something.that.throws.an.error();
  }}
  // this will not be rendered
  element={<HappyPath />}
  // but this will instead
  errorElement={<ErrorBoundary />}
/>

```

If a route doesn't have an `errorElement`, the error will bubble to the nearest parent route with an `errorElement`:



```
<Route
  path="/"
  element={<HappyPath />}
  errorElement={<ErrorBoundary />}
>
  {/* Errors here bubble up to the parent route */}
  <Route path="login" element={<Login />} />
</Route>

```

See:


* [`<Route errorElement>`](../route/error-element)
* [`useRouteError`](../hooks/use-route-error)



Scroll Restoration
-------------------


React Router will emulate the browser's scroll restoration on navigation, waiting for data to load before scrolling. This ensures the scroll position is restored to the right spot.


You can also customize the behavior by restoring based on something other than locations (like a url pathname) and preventing the scroll from happening on certain links (like tabs in the middle of a page).


See:


* [`<ScrollRestoration>`](../components/scroll-restoration)



Web Standard APIs
------------------


React Router is built on web standard APIs. [Loaders](../route/loader) and [actions](../route/action) receive standard Web Fetch API [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) objects and can return [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) objects, too. Cancellation is done with [Abort Signals](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal), search params are handled with [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams), and data mutations are handled with [HTML Forms](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form).


When you get better at React Router, you get better at the web platform.



Search Params
--------------


TODO:



Location State
---------------


TODO:



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/start/overview>

`createBrowserRouter`
======================


This is the recommended router for all React Router web projects. It uses the [DOM History API](https://developer.mozilla.org/en-US/docs/Web/API/History) to update the URL and manage the history stack.


It also enables the v6.4 data APIs like [loaders](../route/loader), [actions](../route/action), [fetchers](../hooks/use-fetcher) and more.



```
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";

import Root, { rootLoader } from "./routes/root";
import Team, { teamLoader } from "./routes/team";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    loader: rootLoader,
    children: [
      {
        path: "team",
        element: <Team />,
        loader: teamLoader,
      },
    ],
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <RouterProvider router={router} />
);

```


Type Declaration
-----------------



```
function createBrowserRouter(
  routes: RouteObject[],
  opts?: {
    basename?: string;
    window?: Window;
  }
): RemixRouter;

```


`routes`
---------


An array of [`Route`](../components/route) objects with nested routes on the `children` property.



```
createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    loader: rootLoader,
    children: [
      {
        path: "events/:id",
        element: <Event />,
        loader: eventLoader,
      },
    ],
  },
]);

```


`basename`
-----------


The basename of the app for situations where you can't deploy to the root of the domain, but a sub directory.



```
createBrowserRouter(routes, {
  basename: "/app",
});

```

The trailing slash will be respected when linking to the root:



```
createBrowserRouter(routes, {
  basename: "/app",
});
<Link to="/" />; // results in <a href="/app" />

createBrowserRouter(routes, {
  basename: "/app/",
});
<Link to="/" />; // results in <a href="/app/" />

```


`window`
---------


Useful for environments like browser devtool plugins or testing to use a different window than the global `window`.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/routers/create-browser-router>

`createMemoryRouter`
=====================


Instead of using the browsers history a memory router manages it's own history stack in memory. It's primarily useful for testing and component development tools like Storybook, but can also be used for running React Router in any non-browser environment.



```
import {
  RouterProvider,
  createMemoryRouter,
} from "react-router-dom";
import * as React from "react";
import {
  render,
  waitFor,
  screen,
} from "@testing-library/react";
import "@testing-library/jest-dom";
import CalendarEvent from "./routes/event";

test("event route", async () => {
  const FAKE_EVENT = { name: "test event" };
  const routes = [
    {
      path: "/events/:id",
      element: <CalendarEvent />,
      loader: () => FAKE_EVENT,
    },
  ];

  const router = createMemoryRouter(routes, {
    initialEntries: ["/", "/events/123"],
    initialIndex: 1,
  });

  render(<RouterProvider router={router} />);

  await waitFor(() => screen.getByRole("heading"));
  expect(screen.getByRole("heading")).toHaveTextContent(
    FAKE_EVENT.name
  );
});

```


Type Declaration
-----------------



```
function createMemoryRouter(
  routes: RouteObject[],
  opts?: {
    basename?: string;
    initialEntries?: InitialEntry[];
    initialIndex?: number;
    window?: Window;
  }
): RemixRouter;

```


`initialEntries`
-----------------


The initial entries in the history stack. This allows you to start a test (or an app) with multiple locations already in the history stack (for testing a back navigation, etc.)



```
createMemoryRouter(routes, {
  initialEntries: ["/", "/events/123"],
});

```


`initialIndex`
---------------


The initial index in the history stack to render. This allows you to start a test at a specific entry. It defaults to the last entry in `initialEntries`.



```
createMemoryRouter(routes, {
  initialEntries: ["/", "/events/123"],
  initialIndex: 1, // start at "/events/123"
});

```


Other props
------------


For all other props, see [`createBrowserRouter`](create-browser-router)



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/routers/create-memory-router>

Examples
=========


You can find many examples, including running version of them on StackBlitz in the GitHub repository:


<https://github.com/remix-run/react-router/tree/dev/examples>



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/start/examples>

Picking a Router
=================


While your app will only use a single router, several routers are available depending on the environment you're app is running in. This document should help you figure out which one to use.



Using v6.4 Data APIs
---------------------


In v6.4, new routers were introduced that support the new data APIs:


* [`createBrowserRouter`](create-browser-router)
* [`createMemoryRouter`](create-memory-router)
* [`createHashRouter`](create-hash-router)


The following routers do not support the data APIs:


* [`<BrowserRouter>`](../router-components/browser-router)
* [`<MemoryRouter>`](memory-router)
* [`<HashRouter>`](../router-components/hash-router)
* [`<NativeRouter>`](native-router)
* [`<StaticRouter>`](static-router)


We recommend updating your app to use one of the new routers from 6.4. The data APIs are currently not supported in React Native, but should be eventually.


The easiest way to quickly update to a v6.4 is to get the help from [`createRoutesFromElements`](../utils/create-routes-from-elements) so you don't need to convert your `<Route>` elements to route objects.



```
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<Root />}>
      <Route path="dashboard" element={<Dashboard />} />
      {/* ... etc. */}
    </Route>
  )
);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

```


Web Projects
-------------


We recommend all web projects use [`createBrowserRouter`](create-browser-router).


It uses the full URL instead of the hash urls (`#this/stuff`) common in web apps before `window.pushState` was standardized. Full URLs are better for SEO, better for server rendering, and are just more compatible with the rest of the web platform.


If you're hosting your app on a static file server, you'll need to configure it to send all requests to your `index.html` to avoid getting 404s.


If for some reason you can't use the full URL, [`createHashRouter`](create-hash-router) is the next best thing.


If you're not interested in the data APIs, you can continue to use [`<BrowserRouter>`](../router-components/browser-router) or, if you can't use full URLs, [`<HashRouter>`](../router-components/hash-router).



Testing
--------


Testing components that use React Router APIs is easiest with [`createMemoryRouter`](create-memory-router) or [`<MemoryRouter>`](memory-router) instead of the routers you use in your app that require DOM history APIs.



React Native
-------------


You will use [`<NativeRouter>`](native-router) from React Native projects.


The data APIs from v6.4 are currently not supported in React Native, but should be eventually.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/routers/picking-a-router>

`<MemoryRouter>`
=================


 Type declaration
```
declare function MemoryRouter(
  props: MemoryRouterProps
): React.ReactElement;

interface MemoryRouterProps {
  basename?: string;
  children?: React.ReactNode;
  initialEntries?: InitialEntry[];
  initialIndex?: number;
}

```
A `<MemoryRouter>` stores its locations internally in an array. Unlike `<BrowserHistory>` and `<HashHistory>`, it isn't tied to an external source, like the history stack in a browser. This makes it ideal for scenarios where you need complete control over the history stack, like testing.


* `<MemoryRouter initialEntries>` defaults to `["/"]` (a single entry at the root `/` URL)
* `<MemoryRouter initialIndex>` defaults to the last index of `initialEntries`



>  **Tip:**
> 
>  Most of React Router's tests are written using a `<MemoryRouter>` as the source of truth, so you can see some great examples of using it by just [browsing through our tests](https://github.com/remix-run/react-router/tree/main/packages/react-router/__tests__).
> 
>  



```
import * as React from "react";
import { create } from "react-test-renderer";
import {
  MemoryRouter,
  Routes,
  Route,
} from "react-router-dom";

describe("My app", () => {
  it("renders correctly", () => {
    let renderer = create(
      <MemoryRouter initialEntries={["/users/mjackson"]}>
        <Routes>
          <Route path="users" element={<Users />}>
            <Route path=":id" element={<UserProfile />} />
          </Route>
        </Routes>
      </MemoryRouter>
    );

    expect(renderer.toJSON()).toMatchSnapshot();
  });
});

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/router-components/memory-router>

`<BrowserRouter>`
==================


 Type declaration
```
declare function BrowserRouter(
  props: BrowserRouterProps
): React.ReactElement;

interface BrowserRouterProps {
  basename?: string;
  children?: React.ReactNode;
  window?: Window;
}

```
A `<BrowserRouter>` stores the current location in the browser's address bar using clean URLs and navigates using the browser's built-in history stack.


`<BrowserRouter window>` defaults to using the current [document's `defaultView`](https://developer.mozilla.org/en-US/docs/Web/API/Document/defaultView), but it may also be used to track changes to another window's URL, in an `<iframe>`, for example.



```
import * as React from "react";
import * as ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <BrowserRouter>
    {/* The rest of your app goes here */}
  </BrowserRouter>,
  root
);

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/router-components/browser-router>

`<HashRouter>`
===============


 Type declaration
```
declare function HashRouter(
  props: HashRouterProps
): React.ReactElement;

interface HashRouterProps {
  basename?: string;
  children?: React.ReactNode;
  window?: Window;
}

```
`<HashRouter>` is for use in web browsers when the URL should not (or cannot) be sent to the server for some reason. This may happen in some shared hosting scenarios where you do not have full control over the server. In these situations, `<HashRouter>` makes it possible to store the current location in the `hash` portion of the current URL, so it is never sent to the server.


`<HashRouter window>` defaults to using the current [document's `defaultView`](https://developer.mozilla.org/en-US/docs/Web/API/Document/defaultView), but it may also be used to track changes to another window's URL, in an `<iframe>`, for example.



```
import * as React from "react";
import * as ReactDOM from "react-dom";
import { HashRouter } from "react-router-dom";

ReactDOM.render(
  <HashRouter>
    {/* The rest of your app goes here */}
  </HashRouter>,
  root
);

```

We strongly recommend you do not use `HashRouter` unless you absolutely have to.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/router-components/hash-router>

`<NativeRouter>`
=================


 Type declaration
```
declare function NativeRouter(
  props: NativeRouterProps
): React.ReactElement;

interface NativeRouterProps extends MemoryRouterProps {}

```
`<NativeRouter>` is the recommended interface for running React Router in a [React Native](https://reactnative.dev) app.


* `<NativeRouter initialEntries>` defaults to `["/"]` (a single entry at the root `/` URL)
* `<NativeRouter initialIndex>` defaults to the last index of `initialEntries`



```
import * as React from "react";
import { NativeRouter } from "react-router-native";

function App() {
  return (
    <NativeRouter>
      {/* The rest of your app goes here */}
    </NativeRouter>
  );
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/router-components/native-router>

`createHashRouter`
===================


This router is useful if you are unable to configure your web server to direct all traffic to your React Router application. Instead of using normal URLs, it will use the hash (#) portion of the URL to manage the "application URL".


Using hash URLs is not recommended.


Other than that, it is functionally the same as [`createBrowserRouter`](create-browser-router).



```
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
  createHashRouter,
  RouterProvider,
} from "react-router-dom";

import Root, { rootLoader } from "./routes/root";
import Team, { teamLoader } from "./routes/team";

const router = createHashRouter([
  {
    path: "/",
    element: <Root />,
    loader: rootLoader,
    children: [
      {
        path: "team",
        element: <Team />,
        loader: teamLoader,
      },
    ],
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <RouterProvider router={router} />
);

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/routers/create-hash-router>

`<StaticRouter>`
=================


 Type declaration
```
declare function StaticRouter(
  props: StaticRouterProps
): React.ReactElement;

interface StaticRouterProps {
  basename?: string;
  children?: React.ReactNode;
  location?: Path | LocationPieces;
}

```
`<StaticRouter>` is used to render a React Router web app in [node](https://nodejs.org). Provide the current location via the `location` prop.


* `<StaticRouter location>` defaults to `"/"`



```
import * as React from "react";
import * as ReactDOMServer from "react-dom/server";
import { StaticRouter } from "react-router-dom/server";
import http from "http";

function requestHandler(req, res) {
  let html = ReactDOMServer.renderToString(
    <StaticRouter location={req.url}>
      {/* The rest of your app goes here */}
    </StaticRouter>
  );

  res.write(html);
  res.end();
}

http.createServer(requestHandler).listen(3000);

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/router-components/static-router>

`<RouterProvider>`
===================


All router objects are passed to this component to render your app and enable the rest of the APIs.



```
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        path: "dashboard",
        element: <Dashboard />,
      },
      {
        path: "about",
        element: <About />,
      },
    ],
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <RouterProvider
    router={router}
    fallbackElement={<BigSpinner />}
  />
);

```


`fallbackElement`
------------------


If you are not server rendering your app, `DataBrowserRouter` will initiate all matching route loaders when it mounts. During this time, you can provide a `fallbackElement` to give the user some indication that the app is working. Make that static hosting TTFB count!



```
<RouterProvider
  router={router}
  fallbackElement={<SpinnerOfDoom />}
/>

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/routers/router-provider>

`<Router>`
===========


 Type declaration
```
declare function Router(
  props: RouterProps
): React.ReactElement | null;

interface RouterProps {
  basename?: string;
  children?: React.ReactNode;
  location: Partial<Location> | string;
  navigationType?: NavigationType;
  navigator: Navigator;
  static?: boolean;
}

```
`<Router>` is the low-level interface that is shared by all router components (like `<BrowserRouter>` and `<StaticRouter>`). In terms of React, `<Router>` is a [context provider](https://reactjs.org/docs/context.html#contextprovider) that supplies routing information to the rest of the app.


You probably never need to render a `<Router>` manually. Instead, you should use one of the higher-level routers depending on your environment. You only ever need one router in a given app.


The `<Router basename>` prop may be used to make all routes and links in your app relative to a "base" portion of the URL pathname that they all share. This is useful when rendering only a portion of a larger app with React Router or when your app has multiple entry points. Basenames are not case-sensitive.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/router-components/router>

`Route`
========


Routes are perhaps the most important part of a React Router app. They couple URL segments to components, data loading and data mutations. Through route nesting, complex application layouts and data dependencies become simple and declarative.


Routes are objects passed to the router creation functions:



```
const router = createBrowserRouter([
  {
    // it renders this element
    element: <Team />,

    // when the URL matches this segment
    path: "teams/:teamId",

    // with this data loaded before rendering
    loader: async ({ request, params }) => {
      return fetch(
        `/fake/api/teams/${params.teamId}.json`,
        { signal: request.signal }
      );
    },

    // performing this mutation when data is submitted to it
    action: async ({ request }) => {
      return updateFakeTeam(await request.formData());
    },

    // and renders this element in case something went wrong
    errorElement: <ErrorBoundary />,
  },
]);

```

You can also declare your routes with JSX and [`createRoutesFromElements`](../utils/create-routes-from-elements), the props to the element are identical to the properties of the route objects:



```
const router = createBrowserRouter(
  createRoutesFromElements(
    <Route
      element={<Team />}
      path="teams/:teamId"
      loader={async ({ params }) => {
        return fetch(
          `/fake/api/teams/${params.teamId}.json`
        );
      }}
      action={async ({ request }) => {
        return updateFakeTeam(await request.formData());
      }}
      errorElement={<ErrorBoundary />}
    />
  )
);

```

Neither style is discouraged and behavior is identical. For the majority of this doc we will use the JSX style because that's what most people are accustomed to in the context of React Router.



Type declaration
-----------------



```
interface RouteObject {
  path?: string;
  index?: boolean;
  children?: React.ReactNode;
  caseSensitive?: boolean;
  id?: string;
  loader?: LoaderFunction;
  action?: ActionFunction;
  element?: React.ReactNode | null;
  errorElement?: React.ReactNode | null;
  handle?: RouteObject["handle"];
  shouldRevalidate?: ShouldRevalidateFunction;
}

```


`path`
-------


The path pattern to match against the URL to determine if this route matches a URL, link href, or form action.


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



```
<Route
  // this path will match URLs like
  // - /teams/hotspur
  // - /teams/real
  path="/teams/:teamId"
  // the matching param will be available to the loader
  loader={({ params }) => {
    console.log(params.teamId); // "hotspur"
  }}
  // and the action
  action={({ params }) => {}}
  element={<Team />}
/>;

// and the element through `useParams`
function Team() {
  let params = useParams();
  console.log(params.teamId); // "hotspur"
}

```

You can have multiple dynamic segments in one route path:



```
<Route path="/c/:categoryId/p/:productId" />;
// both will be available
params.categoryId;
params.productId;

```

Dynamic segments cannot be "partial":


* 🚫 `"/teams-:teamId"`
* ✅ `"/teams/:teamId"`
* 🚫 `"/:category--:productId"`
* ✅ `"/:productSlug"`


You can still support URL patterns like that, you just have to do a bit of your own parsing:



```
function Product() {
  const { productSlug } = useParams();
  const [category, product] = productSlug.split("--");
  // ...
}

```

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



```
<Route
  // this path will match URLs like
  // - /files
  // - /files/one
  // - /files/one/two
  // - /files/one/two/three
  path="/files/*"
  // the matching param will be available to the loader
  loader={({ params }) => {
    console.log(params["*"]); // "one/two"
  }}
  // and the action
  action={({ params }) => {}}
  element={<Team />}
/>;

// and the element through `useParams`
function Team() {
  let params = useParams();
  console.log(params["*"]); // "one/two"
}

```

You can destructure the `*`, you just have to assign it a new name. A common name is `splat`:



```
let { org, "*": splat } = params;

```

### 
Layout Routes


TODO: expand with example


Omitting the path makes this route a "layout route". It participates in UI nesting, but it does not add any segments to the URL.



`index`
--------


Determines if the route is an index route. Index routes render into their parent's [Outlet](outlet) at their parent's URL (like a default child route).



```
<Route path="/teams" element={<Teams />}>
  <Route index element={<TeamsIndex />} />
  <Route path=":teamId" element={<Team />} />
</Route>

```

These special routes can be confusing to understand at first, so we have a guide dedicated to them here: [Index Route](../guides/index-route).



`children`
-----------


(TODO: need to talk about nesting, maybe even a separate doc)



`caseSensitive`
----------------


Instructs the route to match case or not:



```
<Route caseSensitive path="/wEll-aCtuA11y" />

```

* Will match `"wEll-aCtuA11y"`
* Will not match `"well-actua11y"`



`loader`
---------


The route loader is called before the route renders and provides data for the element through [`useLoaderData`](../hooks/use-loader-data).



```
<Route
  path="/teams/:teamId"
  loader={({ params }) => {
    return fetchTeam(params.teamId);
  }}
/>;

function Team() {
  let team = useLoaderData();
  // ...
}

```

If you are not using a data router like [`createBrowserRouter`](../routers/create-browser-router), this will do nothing


Please see the <loader> documentation for more details.



`action`
---------


The route action is called when a submission is sent to the route from a [Form](../components/form), [fetcher](../hooks/use-fetcher), or [submission](../hooks/use-submit).



```
<Route
  path="/teams/:teamId"
  action={({ request }) => {
    const formData = await request.formData();
    return updateTeam(formData);
  }}
/>

```

If you are not using a data router like [`createBrowserRouter`](../routers/create-browser-router), this will do nothing


Please see the <action> documentation for more details.



`element`
----------


The element to render when the route matches the URL.



```
<Route path="/for-sale" element={<Properties />} />

```


`errorElement`
---------------


When a route throws an exception while rendering, in a `loader` or in an `action`, this element will render instead of the normal `element`.



```
<Route
  path="/for-sale"
  // if this throws an error while rendering
  element={<Properties />}
  // or this while loading properties
  loader={() => loadProperties()}
  // or this while creating a property
  action={async ({ request }) =>
    createProperty(await request.formData())
  }
  // then this element will render
  errorElement={<ErrorBoundary />}
/>

```

If you are not using a data router like [`createBrowserRouter`](../routers/create-browser-router), this will do nothing


Please see the [errorElement](error-element) documentation for more details.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/route/route>

`shouldRevalidate`
===================


This function allows you opt-out of revalidation for a route's loader as an optimization.


There are several instances where data is revalidated, keeping your UI in sync with your data automatically:


* After an [`action`](action) is called from a [`<Form>`](../components/form).
* After an [`action`](action) is called from a [`<fetcher.Form>`](../hooks/use-fetcher)
* After an [`action`](action) is called from [`useSubmit`][usesubmit]
* After an [`action`](action) is called from a [`fetcher.submit`](../hooks/use-fetcher)
* When the [URL params](route#dynamic-segments) change for an already rendered route
* When the URL Search params change
* When navigating to the same URL as the current URL


If you define `shouldRevalidate` on a route, it will first check the function before calling the route loader for new data. If the function returns `false`, then the loader *will not* be called and the existing data for that loader will persist on the page.



```
<Route
  path="meals-plans"
  element={<MealPlans />}
  loader={loadMealPlans}
  shouldRevalidate={({ currentUrl }) => {
    // only revalidate if the submission originates from
    // the `/meal-plans/new` route.
    return currentUrl.pathname === "/meal-plans/new";
  }}
>
  <Route
    path="new"
    element={<NewMealPlanForm />}
    // `loadMealPlans` will be revalidated after
    // this action...
    action={createMealPlan}
  />
  <Route
    path=":planId/meal"
    element={<Meal />}
    // ...but not this one because origin the URL
    // is not "/meal-plans/new"
    action={updateMeal}
  />
</Route>

```

Note that this is only for data that has already been loaded, is currently rendered, and will continue to be rendered at the new URL. Data for new routes and fetchers at the new URL will always be fetched initially.


Using this API risks your UI getting out of sync with your data, use with caution!



Type Declaration
-----------------



```
interface ShouldRevalidateFunction {
  (args: {
    currentUrl: URL;
    currentParams: AgnosticDataRouteMatch["params"];
    nextUrl: URL;
    nextParams: AgnosticDataRouteMatch["params"];
    formMethod?: Submission["formMethod"];
    formAction?: Submission["formAction"];
    formEncType?: Submission["formEncType"];
    formData?: Submission["formData"];
    actionResult?: DataResult;
    defaultShouldRevalidate: boolean;
  }): boolean;
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/route/should-revalidate>

FAQs
=====


Here are some questions that people commonly have about React Router v6. You might also find what you're looking for in the [examples](https://github.com/remix-run/react-router/tree/dev/examples).



What happened to withRouter? I need it!
----------------------------------------


This question usually stems from the fact that you're using React class components, which don't support hooks. In React Router v6, we fully embraced hooks and use them to share all the router's internal state. But that doesn't mean you can't use the router. Assuming you can actually use hooks (you're on React 16.8+), you just need a wrapper.



```
import {
  useLocation,
  useNavigate,
  useParams,
} from "react-router-dom";

function withRouter(Component) {
  function ComponentWithRouterProp(props) {
    let location = useLocation();
    let navigate = useNavigate();
    let params = useParams();
    return (
      <Component
        {...props}
        router={{ location, navigate, params }}
      />
    );
  }

  return ComponentWithRouterProp;
}

```


Why does `<Route>` have an `element` prop instead of `render` or `component`?
------------------------------------------------------------------------------


In React Router v6 we switched from using v5's `<Route component>` and `<Route render>` APIs to `<Route element>`. Why is that?


For starters, we see React itself taking the lead here with the `<Suspense fallback={<Spinner />}>` API. The `fallback` prop takes a React **element**, not a **component**. This lets you easily pass whatever props you want to your `<Spinner>` from the component that renders it.


Using elements instead of components means we don't have to provide a `passProps`-style API, so you can get the props you need to your elements. For example, in a component-based API there is no good way to pass props to the `<Profile>` element that is rendered when `<Route path=":userId" component={Profile} />` matches. Most React libraries who take this approach end up with either an API like `<Route component={Profile} passProps={{ animate: true }} />` or use a render prop or higher-order component.


Also, `Route`'s rendering API in v5 was rather large. As we worked on v4/5, the conversation went something like this:



```
// Ah, this is nice and simple!
<Route path=":userId" component={Profile} />

// But wait, how do I pass custom props to the <Profile> element??
// Hmm, maybe we can use a render prop in those situations?
<Route
  path=":userId"
  render={routeProps => (
    <Profile routeProps={routeProps} animate={true} />
  )}
/>

// Ok, now we have two ways to render something with a route. :/

// But wait, what if we want to render something when a route
// *doesn't* match the URL, like a Not Found page? Maybe we
// can use another render prop with slightly different semantics?
<Route
  path=":userId"
  children={({ match }) => (
    match ? (
      <Profile match={match} animate={true} />
    ) : (
      <NotFound />
    )
  )}
/>

// What if I want to get access to the route match, or I need
// to redirect deeper in the tree?
function DeepComponent(routeStuff) {
  // got routeStuff, phew!
}
export default withRouter(DeepComponent);

// Well hey, now at least we've covered all our use cases!
// ... *facepalm*

```

At least part of the reason for this API sprawl was that React did not provide any way for us to get the information from the `<Route>` to your route element, so we had to invent clever ways to get both the route data **and** your own custom props through to your elements: `component`, render props, `passProps` higher-order-components ... until **hooks** came along!


Now, the conversation above goes like this:



```
// Ah, nice and simple API. And it's just like the <Suspense> API!
// Nothing more to learn here.
<Route path=":userId" element={<Profile />} />

// But wait, how do I pass custom props to the <Profile>
// element? Oh ya, it's just an element. Easy.
<Route path=":userId" element={<Profile animate={true} />} />

// Ok, but how do I access the router's data, like the URL params
// or the current location?
function Profile({ animate }) {
  let params = useParams();
  let location = useLocation();
}

// But what about components deep in the tree?
function DeepComponent() {
  // oh right, same as anywhere else
  let navigate = useNavigate();
}

// Aaaaaaaaand we're done here.

```

Another important reason for using the `element` prop in v6 is that `<Route children>` is reserved for nesting routes. You can read more about this in [the guide about getting started](overview#nested-routes) with v6.



How do I add a No Match (404) Route in react-router v6?
--------------------------------------------------------


In v4 we would have just left the path prop off a route. In v5 we would have wrapped our 404 element in a Route and used `path="*"`. In v6 use the new element prop, pass `path="*"` instead:



```
<Route path="*" element={<NoMatch />} />

```


`<Route>` doesn't render? How do I compose?
--------------------------------------------


In v5 the `<Route>` component was just a normal component that was like an `if` statement that rendered when the URL matched its path. In v6, a `<Route>` element doesn't actually ever render, it's simply there for configuration.


In v5, since routes were just components, `MyRoute` will be rendered when the path is "/my-route".



```
let App = () => (
  <div>
    <MyRoute />
  </div>
);

let MyRoute = ({ element, ...rest }) => {
  return (
    <Route path="/my-route" children={<p>Hello!</p>} />
  );
};

```

In v6, however, the `<Route>` is only used for its props, so the following code will never render `<p>Hello!</p>` because `<MyRoute>` has no path that `<Routes>` can see:



```
let App = () => (
  <Routes>
    <MyRoute />
  </Routes>
);

let MyRoute = () => {
  // won't ever render because the path is down here
  return (
    <Route path="/my-route" children={<p>Hello!</p>} />
  );
};

```

You can get the same behavior by:


* Only rendering `<Route>` elements inside of `<Routes>`
* Moving the composition into the `element` prop



```
let App = () => (
  <div>
    <Routes>
      <Route path="/my-route" element={<MyRoute />} />
    </Routes>
  </div>
);

let MyRoute = () => {
  return <p>Hello!</p>;
};

```

Having a full nested route config available statically in `<Routes>` is going to enable a lot of features in `v6.x`, so we encourage you to put your routes in one top-level config. If you really like the idea of components that match the URL independent of any other components, you can make a component that behaves similarly to the v5 `Route` with this:



```
function MatchPath({ path, Comp }) {
  let match = useMatch(path);
  return match ? <Comp {...match} /> : null;
}

// Will match anywhere w/o needing to be in a `<Routes>`
<MatchPath path="/accounts/:id" Comp={Account} />;

```


How do I nest routes deep in the tree?
---------------------------------------


In v5 you could render a `<Route>` or `<Switch>` anywhere you want. You can keep doing the very same thing, but you need to use `<Routes>` (`<Route>` without an 's' will not work). We call these "Descendant `<Routes>`".


It might have looked like this in v5



```
// somewhere up the tree
<Switch>
  <Route path="/users" component={Users} />
</Switch>;

// and now deeper in the tree
function Users() {
  return (
    <div>
      <h1>Users</h1>
      <Switch>
        <Route path="/users/account" component={Account} />
      </Switch>
    </div>
  );
}

```

In v6 it's almost the same:


* Note the `*` in the ancestor routes to get it to match deeper URLs even though it has no direct children
* You no longer need to know the entire child route path, you can use a relative route now



```
// somewhere up the tree
<Routes>
  <Route path="/users/*" element={<Users />} />
</Routes>;

// and now deeper in the tree
function Users() {
  return (
    <div>
      <h1>Users</h1>
      <Routes>
        <Route path="account" element={<Account />} />
      </Routes>
    </div>
  );
}

```

If you had a "floating route" in v5 (not wrapped in a `<Switch>`), simply wrap it in a `<Routes>` instead.



```
// v5
<Route path="/contact" component={Contact} />

// v6
<Routes>
  <Route path="contact" element={<Contact />} />
</Routes>

```


What Happened to Regexp Routes Paths?
--------------------------------------


Regexp route paths were removed for two reasons:


1. Regular expression paths in routes raised a lot of questions for v6's ranked route matching. How do you rank a regex?
2. We were able to shed an entire dependency (path-to-regexp) and cut the package weight sent to your user's browser significantly. If it were added back, it would represent 1/3 of React Router's page weight!


After looking at a lot of use cases, we found we can still meet them without direct regexp path support, so we made the tradeoff to significantly decrease the bundle size and avoid the open questions around ranking regexp routes.


The majority of regexp routes were only concerned about one URL segment at a time and doing one of two things:


1. Matching multiple static values
2. Validating the param in some way (is a number, not a number, etc.)


**Matching generally static values**


A very common route we've seen is a regex matching multiple language codes:



```
function App() {
  return (
    <Switch>
      <Route path={/(en|es|fr)/} component={Lang} />
    </Switch>
  );
}

function Lang({ params }) {
  let lang = params[0];
  let translations = I81n[lang];
  // ...
}

```

These are all actually just static paths, so in v6 you can make three routes and pass the code directly to the component. If you've got a lot of them, make an array and map it into routes to avoid the repetition.



```
function App() {
  return (
    <Routes>
      <Route path="en" element={<Lang lang="en" />} />
      <Route path="es" element={<Lang lang="es" />} />
      <Route path="fr" element={<Lang lang="fr" />} />
    </Routes>
  );
}

function Lang({ lang }) {
  let translations = I81n[lang];
  // ...
}

```

**Doing some sort of param validation**


Another common case was ensuring that parameters were an integer.



```
function App() {
  return (
    <Switch>
      <Route path={/users\/(\d+)/} component={User} />
    </Switch>
  );
}

function User({ params }) {
  let id = params[0];
  // ...
}

```

In this case you have to do a bit of work yourself with the regex inside the matching component:



```
function App() {
  return (
    <Routes>
      <Route path="/users/:id" element={<ValidateUser />} />
      <Route path="/users/*" element={<NotFound />} />
    </Routes>
  );
}

function ValidateUser() {
  let params = useParams();
  let userId = params.id.match(/\d+/);
  if (!userId) {
    return <NotFound />;
  }
  return <User id={params.userId} />;
}

function User(props) {
  let id = props.id;
  // ...
}

```

In v5 if the regex didn't match then `<Switch>` would keep trying to match the next routes:



```
function App() {
  return (
    <Switch>
      <Route path={/users\/(\d+)/} component={User} />
      <Route path="/users/new" exact component={NewUser} />
      <Route
        path="/users/inactive"
        exact
        component={InactiveUsers}
      />
      <Route path="/users/*" component={NotFound} />
    </Switch>
  );
}

```

Looking at this example you might be concerned that in the v6 version your other routes won't get rendered at their URLs because the `:userId` route might match first. But, thanks to route ranking, that is not the case. The "new" and "inactive" routes will rank higher and therefore render at their respective URLs:



```
function App() {
  return (
    <Routes>
      <Route path="/users/:id" element={<ValidateUser />} />
      <Route path="/users/new" element={<NewUser />} />
      <Route
        path="/users/inactive"
        element={<InactiveUsers />}
      />
    </Routes>
  );
}

```

In fact, the v5 version has all sorts of problems if your routes aren't ordered *just right*. V6 completely eliminates this problem.


**Remix Users**


If you're using [Remix](https://remix.run), you can send proper 40x responses to the browser by moving this work into your loader. This also decreases the size of the browser bundles sent to the user because loaders only run on the server.



```
import { useLoaderData } from "remix";

export async function loader({ params }) {
  if (!params.id.match(/\d+/)) {
    throw new Response("", { status: 400 });
  }

  let user = await fakeDb.user.find({
    where: { id: params.id },
  });
  if (!user) {
    throw new Response("", { status: 404 });
  }

  return user;
}

function User() {
  let user = useLoaderData();
  // ...
}

```

Instead of rending your component, remix will render the nearest [catch boundary](https://remix.run/docs/en/v1/api/conventions#catchboundary) instead.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/start/faq>

`action`
=========


Route actions are the "writes" to route <loader> "reads". They provide a way for apps to perform data mutations with simple HTML and HTTP semantics while React Router abstracts away the complexity of asynchronous UI and revalidation. This gives you the simple mental model of HTML + HTTP (where the browser handles the asynchrony and revalidation) with the behavior and UX capabilities of modern SPAs.


This feature only works if using a data router like [`createBrowserRouter`](../routers/create-browser-router)



```
<Route
  path="/song/:songId/edit"
  element={<EditSong />}
  action={async ({ params, request }) => {
    let formData = await request.formData();
    return fakeUpdateSong(params.songId, formData);
  }}
  loader={({ params }) => {
    return fakeGetSong(params.songId);
  }}
/>

```

Actions are called whenever the app sends a non-get submission ("post", "put", "patch", "delete") to your route. This can happen in a few ways:



```
// forms
<Form method="post" action="/songs" />;
<fetcher.Form method="put" action="/songs/123/edit" />;

// imperative submissions
let submit = useSubmit();
submit(data, {
  method: "delete",
  action: "/songs/123",
});
fetcher.submit(data, {
  method: "patch",
  action: "/songs/123/edit",
});

```


`params`
---------


Route params are parsed from [dynamic segments](route#dynamic-segments) and passed to your action. This is useful for figuring out which resource to mutate:



```
<Route
  path="/projects/:projectId/delete"
  action={({ params }) => {
    return fakeDeleteProject(params.projectId);
  }}
/>

```


`request`
----------


This is a [Fetch Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) instance being sent to your route. The most common use case is to parse the [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) from the request



```
<Route
  action={async ({ request }) => {
    let formData = await request.formData();
    // ...
  }}
/>

```


>  A Request?!
> 
>  


It might seem odd at first that actions receive a "request". Have you ever written this line of code?



```
<form
  onSubmit={(event) => {
    event.preventDefault();
    // ...
  }}
/>

```

What exactly are you preventing?


Without JavaScript, just plain HTML and an HTTP web server, that default event that was prevented is actually pretty great. Browsers will serialize all the data in the form into [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) and send it as the body of a new request to your server. Like the code above, React Router [`<Form>`](../components/form) prevents the browser from sending that request and instead sends the request to your route action! This enables highly dynamic web apps with the simple model of HTML and HTTP.


Remember that the values in the `formData` are automatically serialized from the form submission, so your inputs need a `name`.



```
<Form method="post">
  <input name="songTitle" />
  <textarea name="lyrics" />
  <button type="submit">Save</button>
</Form>;

// accessed by the same names
formData.get("songTitle");
formData.get("lyrics");

```

For more information on `formData` see [Working with FormData](../guides/form-data).



Returning Responses
--------------------


While you can return anything you want from an action and get access to it from [`useActionData`](../hooks/use-action-data), you can also return a web [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).


For more information, see the [loader documentation](loader#returning-responses).



Throwing in Actions
--------------------


You can `throw` in your action to break out of the current call stack (stop running the current code) and React Router will start over down the "error path".



```
<Route
  action={async ({ params }) => {
    const res = await fetch(
      `/api/properties/${params.id}`,
      {
        method: "put",
        body: await request.formData(),
      }
    );
    if (!res.ok) throw res;
    return { ok: true };
  }}
/>

```

For more details and expanded use cases, read the [errorElement](error-element) documentation.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/route/action>

`<Link>`
=========


This is the web version of `<Link>`. For the React Native version, [go here](link-native).


 Type declaration
```
declare function Link(props: LinkProps): React.ReactElement;

interface LinkProps
  extends Omit<
    React.AnchorHTMLAttributes<HTMLAnchorElement>,
    "href"
  > {
  replace?: boolean;
  state?: any;
  to: To;
  reloadDocument?: boolean;
}

type To = string | Partial<Path>;

```
A `<Link>` is an element that lets the user navigate to another page by clicking or tapping on it. In `react-router-dom`, a `<Link>` renders an accessible `<a>` element with a real `href` that points to the resource it's linking to. This means that things like right-clicking a `<Link>` work as you'd expect. You can use `<Link reloadDocument>` to skip client side routing and let the browser handle the transition normally (as if it were an `<a href>`).



```
import * as React from "react";
import { Link } from "react-router-dom";

function UsersIndexPage({ users }) {
  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>
            <Link to={user.id}>{user.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

```

A relative `<Link to>` value (that does not begin with `/`) resolves relative to the parent route, which means that it builds upon the URL path that was matched by the route that rendered that `<Link>`. It may contain `..` to link to routes further up the hierarchy. In these cases, `..` works exactly like the command-line `cd` function; each `..` removes one segment of the parent path.


`<Link to>` with a `..` behaves differently from a normal `<a href>` when the current URL ends with `/`. `<Link to>` ignores the trailing slash, and removes one URL segment for each `..`. But an `<a href>` value handles `..` differently when the current URL ends with `/` vs when it does not.



`relative`
-----------


By default, links are relative to the route hierarchy, so `..` will go up one `Route` level. Occasionally, you may find that you have matching URL patterns that do not make sense to be nested, and you're prefer to use relative *path* routing. You can opt into this behavior with `relative`:



```
// Contact and EditContact do not share additional UI layout
<Route path="/" element={<Layout />}>
  <Route path="contacts/:id" element={<Contact />} />
  <Route
    path="contacts/:id/edit"
    element={<EditContact />}
  />
</Route>;

function EditContact() {
  // Since Contact is not a parent of EditContact we need to go up one level
  // in the path, instead of one level in the Route hierarchy
  return (
    <Link to=".." relative="path">
      Cancel
    </Link>
  );
}

```


`preventScrollReset`
---------------------


If you are using [`<ScrollRestoration>`](scroll-restoration), this lets you prevent the scroll position from being reset to the top of the window when the link is clicked.



```
<Link to="?tab=one" preventScrollReset={true} />

```

This does not prevent the scroll position from being restored when the user comes back to the location with the back/forward buttons, it just prevents the reset when the user clicks the link.


An example when you might want this behavior is a list of tabs that manipulate the url search params that aren't at the top of the page. You wouldn't want the scroll position to jump up to the top because it might scroll the toggled content out of the viewport!




 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/components/link>

`<Link>` (React Native)
========================


This is the React Native version of `<Link>`. For the web version, [go here](link).


 Type declaration
```
declare function Link(props: LinkProps): React.ReactElement;

interface LinkProps extends TouchableHighlightProps {
  children?: React.ReactNode;
  onPress?(event: GestureResponderEvent): void;
  replace?: boolean;
  state?: any;
  to: To;
}

```
A `<Link>` is an element that lets the user navigate to another view by tapping it, similar to how `<a>` elements work in a web app. In `react-router-native`, a `<Link>` renders a `TouchableHighlight`. To override default styling and behaviour, please refer to the [Props reference for `TouchableHighlight`](https://reactnative.dev/docs/touchablehighlight#props).



```
import * as React from "react";
import { View, Text } from "react-native";
import { Link } from "react-router-native";

function Home() {
  return (
    <View>
      <Text>Welcome!</Text>
      <Link to="/profile">
        <Text>Visit your profile</Text>
      </Link>
    </View>
  );
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/components/link-native>

`<Outlet>`
===========


 Type declaration
```
interface OutletProps {
  context?: unknown;
}
declare function Outlet(
  props: OutletProps
): React.ReactElement | null;

```
An `<Outlet>` should be used in parent route elements to render their child route elements. This allows nested UI to show up when child routes are rendered. If the parent route matched exactly, it will render a child index route or nothing if there is no index route.



```
function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>

      {/* This element will render either <DashboardMessages> when the URL is
          "/messages", <DashboardTasks> at "/tasks", or null if it is "/"
      */}
      <Outlet />
    </div>
  );
}

function App() {
  return (
    <Routes>
      <Route path="/" element={<Dashboard />}>
        <Route
          path="messages"
          element={<DashboardMessages />}
        />
        <Route path="tasks" element={<DashboardTasks />} />
      </Route>
    </Routes>
  );
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/components/outlet>

Route APIs
===========


Because the API and use cases for `<Route />` includes data loading, mutations, and more, `<Route>` has its own documentation category.


Please refer to:


* [`<Route>`](../route/route)
* [`loader`](../route/loader)
* [`action`](../route/action)
* [`errorElement`](../route/error-element)
* [`shouldRevalidate`](../route/should-revalidate)



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/components/route>

`<Routes>`
===========


Rendered anywhere in the app, `<Routes>` will match a set of child routes from the current [location](../hook/location).



```
interface RoutesProps {
  children?: React.ReactNode;
  location?: Partial<Location> | string;
}

<Routes location>
  <Route />
</Routes>;

```

If you're using a data router like [`createBrowserRouter`](../routers/create-browser-router) it is uncommon to use this component as it does not participate in data loading.


Whenever the location changes, `<Routes>` looks through all its child routes to find the best match and renders that branch of the UI. `<Route>` elements may be nested to indicate nested UI, which also correspond to nested URL paths. Parent routes render their child routes by rendering an [`<Outlet>`](outlet).



```
<Routes>
  <Route path="/" element={<Dashboard />}>
    <Route
      path="messages"
      element={<DashboardMessages />}
    />
    <Route path="tasks" element={<DashboardTasks />} />
  </Route>
  <Route path="about" element={<AboutPage />} />
</Routes>

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/components/routes>

`loader`
=========


Each route can define a "loader" function to provide data to the route element before it renders.


This feature only works if using a data router, see [Picking a Router](../routers/picking-a-router)



```
createBrowserRouter([
  {
    element: <Teams />,
    path: "teams",
    loader: async () => {
      return fakeDb.from("teams").select("*");
    },
    children: [
      {
        element: <Team />,
        path: ":teamId",
        loader: async ({ params }) => {
          return fetch(`/api/teams/${params.teamId}.json`);
        },
      },
    ],
  },
]);

```

As the user navigates around the app, the loaders for the next matching branch of routes will be called in parallel and their data made available to components through [`useLoaderData`](../hooks/use-loader-data).



`params`
---------


Route params are parsed from [dynamic segments](route#dynamic-segments) and passed to your loader. This is useful for figuring out which resource to load:



```
createBrowserRouter([
  {
    path: "/teams/:teamId",
    loader: ({ params }) => {
      return fakeGetTeam(params.teamId);
    },
  },
]);

```

Note that the `:teamId` in the path is parsed as provided as `params.teamId` by the same name.



`request`
----------


This is a [Fetch Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) instance being made to your application.



```
function loader({ request }) {}

```


>  A request?!
> 
>  


It might seem odd at first that loaders receive a "request". Consider that `<Link>` does something like the following code and ask yourself, "what default behavior is being prevented here?".



```
<a
  href={props.to}
  onClick={(event) => {
    event.preventDefault();
    navigate(props.to);
  }}
/>

```

Without React Router, the browser would have made a *Request* to your server, but React Router prevented it! Instead of the browser sending the request to your server, React Router sends the request to your loaders.


The most common use case is creating a [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) and reading the [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) from it:



```
function loader({ request }) {
  const url = new URL(request.url);
  const searchTerm = url.searchParams.get("q");
  return searchProducts(searchTerm);
}

```

Note that the APIs here are not React Router specific, but rather standard web objects: [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request), [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL), [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams).



Returning Responses
--------------------


While you can return anything you want from a loader and get access to it from [`useLoaderData`](../hooks/use-loader-data), you can also return a web [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).


This might not seem immediately useful, but consider `fetch`. Since the return value of of `fetch` is a Response, and loaders understand responses, many loaders can return a simple fetch!



```
// an HTTP/REST API
function loader({ request }) {
  return fetch("/api/teams.json", {
    signal: request.signal,
  });
}

// or even a graphql endpoint
function loader({ request, params }) {
  return fetch("/_gql", {
    signal: request.signal,
    method: "post",
    body: JSON.stringify({
      query: gql`...`,
      params: params,
    }),
  });
}

```

You can construct the response yourself as well:



```
function loader({ request, params }) {
  const data = { some: "thing" };
  return new Response(JSON.stringify(data), {
    status: 200,
    headers: {
      "Content-Type": "application/json; utf-8",
    },
  });
}

```

React Router will automatically call `response.json()` so your components don't need to parse it while rendering:



```
function SomeRoute() {
  const data = useLoaderData();
  // { some: "thing" }
}

```

Using the [`json`](../fetch/json) utility simplifies this so you don't have to construct them yourself. This next example is effectively the same as the previous example:



```
import { json } from "react-router-dom";

function loader({ request, params }) {
  const data = { some: "thing" };
  return json(data, { status: 200 });
}

```

If you're planning an upgrade to Remix, returning responses from every loader will make the migration smoother.



Throwing in Loaders
--------------------


You can `throw` in your loader to break out of the current call stack (stop running the current code) and React Router will start over down the "error path".



```
function loader({ request, params }) {
  const res = await fetch(`/api/properties/${params.id}`);
  if (res.status === 404) {
    throw new Response("Not Found", { status: 404 });
  }
  return res.json();
}

```

For more details, read the [`errorElement`](error-element) documentation.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/route/loader>

React Router Examples
======================


Welcome to the examples for React Router.


Here you'll find various examples of using React Router to accomplish certain tasks. Each example is a complete application including a build and even a button to preview a live instance of the app so you can play with it. You'll most often be interested in checking out the code in `src/App.tsx` (or `src/App.js`), but we included the entire source code for the app for completeness.


Also, remember to check out the README!


Enjoy!



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples>

`<Navigate>`
=============


 Type declaration
```
declare function Navigate(props: NavigateProps): null;

interface NavigateProps {
  to: To;
  replace?: boolean;
  state?: any;
  relative?: RelativeRoutingType;
}

```
A `<Navigate>` element changes the current location when it is rendered. It's a component wrapper around [`useNavigate`](../hooks/use-navigate), and accepts all the same arguments as props.


Having a component-based version of the `useNavigate` hook makes it easier to use this feature in a [`React.Component`](https://reactjs.org/docs/react-component.html) subclass where hooks are not able to be used.



```
import * as React from "react";
import { Navigate } from "react-router-dom";

class LoginForm extends React.Component {
  state = { user: null, error: null };

  async handleSubmit(event) {
    event.preventDefault();
    try {
      let user = await login(event.target);
      this.setState({ user });
    } catch (error) {
      this.setState({ error });
    }
  }

  render() {
    let { user, error } = this.state;
    return (
      <div>
        {error && <p>{error.message}</p>}
        {user && (
          <Navigate to="/dashboard" replace={true} />
        )}
        <form
          onSubmit={(event) => this.handleSubmit(event)}
        >
          <input type="text" name="username" />
          <input type="password" name="password" />
        </form>
      </div>
    );
  }
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/components/navigate>

Error Boundaries
=================


This example demonstrates some of the basic features of React Router's `errorElement` boundaries, including:


* Handling thrown `loader` errors
* Handling render errors
* Re-throwing errors from an `errorElement`



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/error-boundaries>

`<NavLink>`
============


 Type declaration
```
declare function NavLink(
  props: NavLinkProps
): React.ReactElement;

interface NavLinkProps
  extends Omit<
    LinkProps,
    "className" | "style" | "children"
  > {
  caseSensitive?: boolean;
  children?:
    | React.ReactNode
    | ((props: { isActive: boolean }) => React.ReactNode);
  className?:
    | string
    | ((props: {
        isActive: boolean;
      }) => string | undefined);
  end?: boolean;
  style?:
    | React.CSSProperties
    | ((props: {
        isActive: boolean;
      }) => React.CSSProperties);
}

```
A `<NavLink>` is a special kind of [`<Link>`](link) that knows whether or not it is "active". This is useful when building a navigation menu such as a breadcrumb or a set of tabs where you'd like to show which of them is currently selected. It also provides useful context for assistive technology like screen readers.


By default, an `active` class is added to a `<NavLink>` component when it is active. This provides the same simple styling mechanism for most users who are upgrading from v5. One difference as of `v6.0.0-beta.3` is that `activeClassName` and `activeStyle` have been removed from `NavLinkProps`. Instead, you can pass a function to either `style` or `className` that will allow you to customize the inline styling or the class string based on the component's active state. You can also pass a function as children to customize the content of the `<NavLink>` component based on their active state, specially useful to change styles on internal elements.



```
import * as React from "react";
import { NavLink } from "react-router-dom";

function NavList() {
  // This styling will be applied to a <NavLink> when the
  // route that it links to is currently selected.
  let activeStyle = {
    textDecoration: "underline",
  };

  let activeClassName = "underline";

  return (
    <nav>
      <ul>
        <li>
          <NavLink
            to="messages"
            style={({ isActive }) =>
              isActive ? activeStyle : undefined
            }
          >
            Messages
          </NavLink>
        </li>
        <li>
          <NavLink
            to="tasks"
            className={({ isActive }) =>
              isActive ? activeClassName : undefined
            }
          >
            Tasks
          </NavLink>
        </li>
        <li>
          <NavLink to="tasks">
            {({ isActive }) => (
              <span
                className={
                  isActive ? activeClassName : undefined
                }
              >
                Tasks
              </span>
            )}
          </NavLink>
        </li>
      </ul>
    </nav>
  );
}

```

If you prefer the v5 API, you can create your own `<NavLink />` as a wrapper component:



```
import * as React from "react";
import { NavLink as BaseNavLink } from "react-router-dom";

const NavLink = React.forwardRef(
  ({ activeClassName, activeStyle, ...props }, ref) => {
    return (
      <BaseNavLink
        ref={ref}
        {...props}
        className={({ isActive }) =>
          [
            props.className,
            isActive ? activeClassName : null,
          ]
            .filter(Boolean)
            .join(" ")
        }
        style={({ isActive }) => ({
          ...props.style,
          ...(isActive ? activeStyle : null),
        })}
      />
    );
  }
);

```

If the `end` prop is used, it will ensure this component isn't matched as "active" when its descendant paths are matched. For example, to render a link that is only active at the website root and not any other URLs, you can use:



```
<NavLink to="/" end>
  Home
</NavLink>

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/components/nav-link>

Basic Example
==============


This example demonstrates some of the basic features of React Router, including:


* Layouts and nested `<Route>`s
* Index `<Route>`s
* Catch-all `<Route>`s
* Using `<Outlet>` as a placeholder for child routes
* Using `<Link>`s for navigation



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/basic>

Data Routers
=============


This example demonstrates some of the basic features of Data Router, including:


* Loader functions
* Action functions
* and  navigations



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/notes>

`<ScrollRestoration />`
========================


This component will emulate the browser's scroll restoration on location changes after loaders have completed to ensure the scroll position is restored to the right spot, even across domains.


You should only render one of these and it's recommended you render it in the root route of your app:



```
import { ScrollRestoration } from "react-router-dom";

function RootRouteComponent() {
  return (
    <div>
      {/* ... */}
      <ScrollRestoration />
    </div>
  );
}

```


`getKey`
---------


Optional prop that defines the key React Router should use to restore scroll positions.



```
<ScrollRestoration
  getKey={(location, matches) => {
    // default behavior
    return location.key;
  }}
/>

```

By default it uses `location.key`, emulating the browser's default behavior without client side routing. The user can navigate to the same URL multiple times in the stack and each entry gets its own scroll position to restore.


Some apps may want to override this behavior and restore position based on something else. Consider a social app that has four primary pages:


* "/home"
* "/messages"
* "/notifications"
* "/search"


If the user starts at "/home", scrolls down a bit, clicks "messages" in the navigation menu, then clicks "home" in the navigation menu (not the back button!) there will be three entries in the history stack:


By default, React Router (and the browser) will have two different scroll positions stored for `1` and `3` even though they have the same URL. That means as the user navigated from `2` → `3` the scroll position goes to the top instead of restoring to where it was in `1`.


A solid product decision here is to keep the users scroll position on the home feed no matter how they got there (back button or new link clicks). For this, you'd want to use the `location.pathname` as the key.



```
<ScrollRestoration
  getKey={(location, matches) => {
    return location.pathname;
  }}
/>

```

Or you may want to only use the pathname for some paths, and use the normal behavior for everything else:



```
<ScrollRestoration
  getKey={(location, matches) => {
    const paths = ["/home", "/notifications"];
    return paths.includes(location.pathname)
      ? // home and notifications restore by pathname
        location.pathname
      : // everything else by location like the browser
        location.key;
  }}
/>

```


Preventing Scroll Reset
------------------------


When navigation creates new scroll keys, the scroll position is reset to the top of the page. You can prevent the "scroll to top" behavior from your links:



```
<Link preventScrollReset={true} />

```

See also: [`<Link preventScrollReset>`](link#preventscrollreset)



Scroll Flashing
----------------


Without a server side rendering framework like [Remix](https://remix.run), you may experience some scroll flashing on initial page loads. This is because React Router can't restore scroll position until your JS bundles have downloaded, data has loaded, and the full page has rendered (if you're rendering a spinner, the viewport is likely not the size it was when the scroll position was saved).


Server Rendering frameworks can prevent scroll flashing because they can send a fully formed document on the initial load, so scroll can be restored when the page first renders.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/components/scroll-restoration>

Data Routers
=============


This example demonstrates some of the basic features of Data Router, including:


* Loader functions
* Action functions
* and  navigations
* <fetcher.Form> submissions



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/data-router>

Auth Example
=============


This example demonstrates how to restrict access to routes to authenticated users.


Be sure to pay attention to the following features:


* The use of the `useNavigate()` hook and the `<Navigate>` component for navigating both imperatively after the login form is submitted and declaratively when a non-authenticated user visits a particular route
* The use of `location.state` to preserve the previous location so you can send the user there after they authenticate
* The use of `navigate("...", { replace: true })` to replace the `/login` route in the history stack so the user doesn't return to the login page when clicking the back button after logging in



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/auth>

Lazy Loading Example
=====================


This example demonstrates how to lazily load both


* individual route elements
* entire portions of your route hierarchy


on demand using `React.lazy()` and dynamic `import()`. Using this technique, pages that are not required on the home page can be split out into separate bundles, thereby decreasing load time on the initial page and improving performance.



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/lazy-loading>

Main Concepts
==============


This document needs to be updated for 6.4 data APIs


This document is a deep dive into the core concepts behind routing as implemented in React Router. It's pretty long, so if you're looking for a more practical guide check out our [quick start tutorial](tutorial).


You might be wondering what exactly React Router does. How can it help you build your app? What exactly is a **router**, anyway?


If you've ever had any of these questions, or you'd just like to dig into the fundamental pieces of routing, you're in the right place. This document contains detailed explanations of all the core concepts behind routing as implemented in React Router.


Please don't let this document overwhelm you! For everyday use, React Router is pretty simple. You don't need to go this deep to use it.


React Router isn't just about matching a url to a function or component: it's about building a full user interface that maps to the URL, so it might have more concepts in it than you're used to. We'll go into detail on the three main jobs of React Router:


1. Subscribing and manipulating the [history stack](#history-stack)
2. Matching the [URL](#url) to your [routes](#route-config)
3. Rendering a nested UI from the [route matches](#matches)



Definitions
------------


But first, some definitions! There are a lot of different ideas around routing from back and front end frameworks. Sometimes a word in one context might have different meaning than another.


Here are some words we use a lot when we talk about React Router. The rest of this guide will go into more detail on each one.


* **URL** - The URL in the address bar. A lot of people use the term "URL" and "route" interchangeably, but this is not a route in React Router, it's just a URL.
* **Location** - This is a React Router specific object that is based on the built-in browser's `window.location` object. It represents "where the user is at". It's mostly an object representation of the URL but has a bit more to it than that.
* **Location State** - A value that persists with a [location](#location) that isn't encoded in the [URL](#url). Much like hash or search params (data encoded in the URL), but stored invisibly in the browser's memory.
* **History Stack** - As the user navigates, the browser keeps track of each [location](#location) in a stack. If you click and hold the back button in a browser you can see the browser's history stack right there.
* **Client Side Routing (CSR)** - A plain HTML document can link to other documents and the browser handles the [history stack](#history-stack) itself. Client Side Routing enables developers to manipulate the browser history stack without making a document request to the server.
* **History** - An object that allows React Router to subscribe to changes in the [URL](#url) as well as providing APIs to manipulate the browser [history stack](#history-stack) programmatically.
* **History Action** - One of `POP`, `PUSH`, or `REPLACE`. Users can arrive at a [URL](#url) for one of these three reasons. A push when a new entry is added to the history stack (typically a link click or the programmer forced a navigation). A replace is similar except it replaces the current entry on the stack instead of pushing a new one. Finally, a pop happens when the user clicks the back or forward buttons in the browser chrome.
* **Segment** - The parts of a [URL](#url) or [path pattern](#path-pattern) between the `/` characters. For example, "/users/123" has two segments.
* **Path Pattern** - These look like URLs but can have special characters for matching URLs to routes, like **dynamic segments** (`"/users/:userId"`) or **star segments** (`"/docs/*"`). They aren't URLs, they're patterns that React Router will match.
* **Dynamic Segment** - A segment of a path pattern that is dynamic, meaning it can match any values in the segment. For example the pattern `/users/:userId` will match URLs like `/users/123`
* **URL Params** - The parsed values from the URL that matched a [dynamic segment](#dynamic-segment).
* **Router** - Stateful, top-level component that makes all the other components and hooks work.
* **Route Config** - A tree of **routes objects** that will be ranked and matched (with nesting) against the current location to create a branch of **route matches**.
* **Route** - An object or Route Element typically with a shape of `{ path, element }` or `<Route path element>`. The `path` is a path pattern. When the path pattern matches the current URL, the element will be rendered.
* **Route Element** - Or `<Route>`. This element's props are read to create a [route](#route) by `<Routes>`, but otherwise does nothing.
* **Nested Routes** - Because routes can have children and each route defines a portion of the [URL](#url) through [segments](#segment), a single URL can match multiple routes in a nested "branch" of the tree. This enables automatic layout nesting through [outlet](#outlet), [relative links](#relative-links), and more.
* **Relative links** - Links that don't start with `/` will inherit the closest route in which they are rendered. This makes it easy to link to deeper URLs without having to know and build up the entire path.
* **Match** - An object that holds information when a route matches the URL, like the [url params](#url-params) and pathname that matched.
* **Matches** - An array of routes (or branch of the [route config](#route-config)) that matches the current [location](#location). This structure enables [nested routes](#nested-routes).
* **Parent Route** - A route with child routes.
* **Outlet** - A component that renders the next match in a set of [matches](#match).
* **Index Route** - A child route with no path that renders in the parent's [outlet](#outlet) at the parent's [URL](#url).
* **Layout Route** - A **parent route** without a path, used exclusively for grouping child routes inside a specific layout.



History and Locations
----------------------


Before React Router can do anything, it has to be able to subscribe to changes in the browser [history stack](#history-stack).


Browsers maintain their own history stack as the user navigates around. That's how the back and forward buttons can work. In a traditional website (HTML documents without JavaScript) the browser will make requests to the server every time the user clicks a link, submits a form, or clicks the back and forward buttons.


For example, consider the user:


1. clicks a link to `/dashboard`
2. clicks a link to `/accounts`
3. clicks a link to `/customers/123`
4. clicks the back button
5. clicks a link to `/dashboard`


The history stack will change as follows where **bold** entries denote the current [URL](#url):


1. **`/dashboard`**
2. `/dashboard`, **`/accounts`**
3. `/dashboard`, `/accounts`, **`/customers/123`**
4. `/dashboard`, **`/accounts`**, `/customers/123`
5. `/dashboard`, `/accounts`, **`/dashboard`**


### 
History Object


With **client side routing**, developers are able to manipulate the browser [history stack](#history-stack) programmatically. For example, we can write some code like this to change the [URL](#url) without the browsers default behavior of making a request to the server:



```
<a
  href="/contact"
  onClick={(event) => {
    // stop the browser from changing the URL and requesting the new document
    event.preventDefault();
    // push an entry into the browser history stack and change the URL
    window.history.pushState({}, undefined, "/contact");
  }}
/>

```

For illustration only, don't use `window.history.pushState` directly in React Router


This code changes the [URL](#url) but doesn't do anything for the UI. We would need to write some more code that changed some state somewhere to get the UI to change to the contact page. The trouble is, the browser doesn't give us a way to "listen to the URL" and subscribe to changes like this.


Well, that's not totally true. We can listen for changes to the URL via [pop](#history-actions) events:



```
window.addEventListener("popstate", () => {
  // URL changed!
});

```

But that only fires when the user clicks the back or forward buttons. There is no event for when the programmer called `window.history.pushState` or `window.history.replaceState`.


That's where a React Router specific `history` object comes into play. It provides a way to "listen for [URL](#url)" changes whether the [history action](#history-actions) is **push**, **pop**, or **replace**.



```
let history = createBrowserHistory();
history.listen(({ location, action }) => {
  // this is called whenever new locations come in
  // the action is POP, PUSH, or REPLACE
});

```

Apps don't need to set up their own history objects--that's job of `<Router>`. It sets up one of these objects, subscribe to changes in the [history stack](#history-stack), and finally updates its state when the [URL](#url) changes. This causes the app to re-render and the correct UI to display. The only thing it needs to put on state is a `location`, everything else works from that single object.


### 
Locations


The browser has a location object on `window.location`. It tells you information about the [URL](#url) but also has some methods to change it:



```
window.location.pathname; // /getting-started/concepts/
window.location.hash; // #location
window.location.reload(); // force a refresh w/ the server
// and a lot more

```

For illustration. You don't typically work with `window.location` in a React Router app


Instead of using `window.location`, React Router has the concept of a [location](#location) that's patterned after `window.location` but is much simpler. It looks like this:



```
{
  pathname: "/bbq/pig-pickins",
  search: "?campaign=instagram",
  hash: "#menu",
  state: null,
  key: "aefz24ie"
}

```

The first three: `{ pathname, search, hash }` are exactly like `window.location`. If you just add up the three you'll get the [URL](#url) the user sees in the browser:



```
location.pathname + location.search + location.hash;
// /bbq/pig-pickins?campaign=instagram#menu

```

The last two, `{ state, key }`, are React Router specific.


**Location Pathname**


This is the part of [URL](#url) after the origin, so for `https://example.com/teams/hotspurs` the pathname is `/teams/hotspurs`. This is the only part of the location that routes match against.


**Location Search**


People use a lot of different terms for this part of the [URL](#url):


* location search
* search params
* URL search params
* query string


In React Router we call it the "location search". However, location search is a serialized version of [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams). So sometimes we might call it "URL search params" as well.



```
// given a location like this:
let location = {
  pathname: "/bbq/pig-pickins",
  search: "?campaign=instagram&popular=true",
  hash: "",
  state: null,
  key: "aefz24ie",
};

// we can turn the location.search into URLSearchParams
let params = new URLSearchParams(location.search);
params.get("campaign"); // "instagram"
params.get("popular"); // "true"
params.toString(); // "campaign=instagram&popular=true",

```

When being precise, refer to the serialized string version as "search" and the parsed version as "search params", but it's common to use the terms interchangeably when precision isn't important.


**Location Hash**


Hashes in URLs indicate a scroll position *on the current page*. Before the `window.history.pushState` API was introduced, web developers did client side routing exclusively with the hash portion of the [URL](#url), it was the only part we could manipulate without making a new request to the server. However, today we can use it for its designed purpose.


**Location State**


You may have wondered why the `window.history.pushState()` API is called "push state". State? Aren't we just changing the [URL](#url)? Shouldn't it be `history.push`? Well, we weren't in the room when the API was designed, so we're not sure why "state" was the focus, but it is a cool feature of browsers nonetheless.


Browsers let us persist information about a navigation by passing a value to `pushState`. When the user clicks back, the value on `history.state` changes to whatever was "pushed" before.



```
window.history.pushState("look ma!", undefined, "/contact");
window.history.state; // "look ma!"
// user clicks back
window.history.state; // undefined
// user clicks forward
window.history.state; // "look ma!"

```

For illustration. You don't read `history.state` directly in React Router apps


React Router takes advantage of this browser feature, abstracts it a bit, and surfaces the values on the `location` instead of `history`.


You can think about `location.state` just like `location.hash` or `location.search` except instead of putting the values in the [URL](#url) it's hidden--like a super secret piece of the URL only the programmer knows about.


A couple of great use-cases for location state are:


* Telling the next page where the user came from and branching the UI. The most popular implementation here is showing a record in a modal if the user clicked on an item in a grid view, but if they show up to the URL directly, show the record in its own layout (pinterest, old instagram).
* Sending a partial record from a list to the next screen so it can render the partial data immediately and then fetching the rest of the data afterward.


You set location state in two ways: on `<Link>` or `navigate`:



```
<Link to="/pins/123" state={{ fromDashboard: true }} />;

let navigate = useNavigate();
navigate("/users/123", { state: partialUser });

```

And on the next page you can access it with `useLocation`:



```
let location = useLocation();
location.state;

```

Location state values will get serialized, so something like `new Date()` will be turned into a string.


**Location Key**


Each location gets a unique key. This is useful for advanced cases like location-based scroll management, client side data caching, and more. Because each new location gets a unique key, you can build abstractions that store information in a plain object, `new Map()`, or even `locationStorage`.


For example, a very basic client side data cache could store values by location key (and the fetch [URL](#url)) and skip fetching the data when the user clicks back into it:



```
let cache = new Map();

function useFakeFetch(URL) {
  let location = useLocation();
  let cacheKey = location.key + URL;
  let cached = cache.get(cacheKey);

  let [data, setData] = useState(() => {
    // initialize from the cache
    return cached || null;
  });

  let [state, setState] = useState(() => {
    // avoid the fetch if cached
    return cached ? "done" : "loading";
  });

  useEffect(() => {
    if (state === "loading") {
      let controller = new AbortController();
      fetch(URL, { signal: controller.signal })
        .then((res) => res.json())
        .then((data) => {
          if (controller.signal.aborted) return;
          // set the cache
          cache.set(cacheKey, data);
          setData(data);
        });
      return () => controller.abort();
    }
  }, [state, cacheKey]);

  useEffect(() => {
    setState("loading");
  }, [URL]);

  return data;
}

```


Matching
---------


On the initial render, and when the [history stack](#history-stack) changes, React Router will match the [location](#location) against your [route config](#route-config) to come up with a set of [matches](#match) to render.


### 
Defining Routes


A route config is a tree of [routes](#route) that looks something like this:



```
<Routes>
  <Route path="/" element={<App />}>
    <Route index element={<Home />} />
    <Route path="teams" element={<Teams />}>
      <Route path=":teamId" element={<Team />} />
      <Route path=":teamId/edit" element={<EditTeam />} />
      <Route path="new" element={<NewTeamForm />} />
      <Route index element={<LeagueStandings />} />
    </Route>
  </Route>
  <Route element={<PageLayout />}>
    <Route path="/privacy" element={<Privacy />} />
    <Route path="/tos" element={<Tos />} />
  </Route>
  <Route path="contact-us" element={<Contact />} />
</Routes>

```

The `<Routes>` component recurses through its `props.children`, strips their props, and generates an object like this:



```
let routes = [
  {
    element: <App />,
    path: "/",
    children: [
      {
        index: true,
        element: <Home />,
      },
      {
        path: "teams",
        element: <Teams />,
        children: [
          {
            index: true,
            element: <LeagueStandings />,
          },
          {
            path: ":teamId",
            element: <Team />,
          },
          {
            path: ":teamId/edit",
            element: <EditTeam />,
          },
          {
            path: "new",
            element: <NewTeamForm />,
          },
        ],
      },
    ],
  },
  {
    element: <PageLayout />,
    children: [
      {
        element: <Privacy />,
        path: "/privacy",
      },
      {
        element: <Tos />,
        path: "/tos",
      },
    ],
  },
  {
    element: <Contact />,
    path: "/contact-us",
  },
];

```

In fact, instead of `<Routes>` you can use the hook `useRoutes(routesGoHere)` instead. That's all `<Routes>` is doing.


As you can see, routes can define multiple [segments](#segment) like `:teamId/edit`, or just one like `:teamId`. All of the segments down a branch of the [route config](#route-config) are added together to create a final [path pattern](#path-pattern) for a route.


### 
Match Params


Note the `:teamId` segments. This is what we call a [dynamic segment](#dynamic-segment) of the [path pattern](#path-pattern), meaning it doesn't match the URL statically (the actual characters) but it matches it dynamically. Any value can fill in for `:teamId`. Both `/teams/123` or `/teams/cupcakes` will match. We call the parsed values [URL params](#url-params). So in this case our `teamId` param would be `"123"` or `"cupcakes"`. We'll see how to use them in your app in the [Rendering](#rendering) section.


### 
Ranking Routes


If we add up all the segments of all the branches of our [route config](#route-config), we end up with the following path patterns that our app responds to:



```
[
  "/",
  "/teams",
  "/teams/:teamId",
  "/teams/:teamId/edit",
  "/teams/new",
  "/privacy",
  "/tos",
  "/contact-us",
];

```

Now this is where things get really interesting. Consider the [URL](#url) `/teams/new`. Which pattern in that list matches the URL?


That's right, two of them!


React Router has to make a decision here, there can be only one. Many routers, both client side and server side, will simply process the patterns in the order in which they were defined. First to match wins. In this case we would match `/` and render the `<Home/>` component. Definitely not what we wanted. These kinds of routers require us to order our routes perfectly to get the expected result. This is how React Router has worked up until v6, but now it's much smarter.


Looking at those patterns, you intuitively know that we want `/teams/new` to match the URL `/teams/new`. It's a perfect match! React Router also knows that. When matching, it will rank your routes according the number of segments, static segments, dynamic segments, star patterns, etc. and pick the most specific match. You'll never have to think about ordering your routes.


### 
Pathless Routes


You may have noticed the weird routes from earlier:



```
<Route index element={<Home />} />
<Route index element={<LeagueStandings />} />
<Route element={<PageLayout />} />

```

They don't even have a path, how can they be a route? This is where the word "route" in React Router is used pretty loosely. `<Home/>` and `<LeagueStandings/>` are [index routes](#index-route) and `<PageLayout/>` is a [layout route](#layout-route). We'll discuss how they work in the [Rendering](#rendering) section. Neither really has much to do with matching.


### 
Route Matches


When a route matches the URL, it's represented by a [match](#match) object. A match for `<Route path=":teamId" element={<Team/>}/>` would look something like this:



```
{
  pathname: "/teams/firebirds",
  params: {
    teamId: "firebirds"
  },
  route: {
    element: <Team />,
    path: ":teamId"
  }
}

```

`pathname` holds the portion of the URL that matched this route (in our case it's all of it). `params` holds the parsed values from any [dynamic segments](#dynamic-segment) that matched. Note that the param's object keys map directly to the name of the segment: `:teamId` becomes `params.teamId`.


Because our routes are a tree, a single URL can match an entire branch of the tree. Consider the URL `/teams/firebirds`, it would be the following route branch:



```
<Routes>
  <Route path="/" element={<App />}>
    <Route index element={<Home />} />
    <Route path="teams" element={<Teams />}>
      <Route path=":teamId" element={<Team />} />
      <Route path=":teamId/edit" element={<EditTeam />} />
      <Route path="new" element={<NewTeamForm />} />
      <Route index element={<LeagueStandings />} />
    </Route>
  </Route>
  <Route element={<PageLayout />}>
    <Route path="/privacy" element={<Privacy />} />
    <Route path="/tos" element={<Tos />} />
  </Route>
  <Route path="contact-us" element={<Contact />} />
</Routes>

```

React Router will create an array of [matches](#match) from these routes and the url so it can render a nested UI that matches the route nesting.



```
[
  {
    pathname: "/",
    params: null,
    route: {
      element: <App />,
      path: "/",
    },
  },
  {
    pathname: "/teams",
    params: null,
    route: {
      element: <Teams />,
      path: "teams",
    },
  },
  {
    pathname: "/teams/firebirds",
    params: {
      teamId: "firebirds",
    },
    route: {
      element: <Team />,
      path: ":teamId",
    },
  },
];

```


Rendering
----------


The final concept is rendering. Consider that the entry to your app looks like this:



```
const root = ReactDOM.createRoot(
  document.getElementById("root")
);
root.render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<App />}>
        <Route index element={<Home />} />
        <Route path="teams" element={<Teams />}>
          <Route path=":teamId" element={<Team />} />
          <Route path="new" element={<NewTeamForm />} />
          <Route index element={<LeagueStandings />} />
        </Route>
      </Route>
      <Route element={<PageLayout />}>
        <Route path="/privacy" element={<Privacy />} />
        <Route path="/tos" element={<Tos />} />
      </Route>
      <Route path="contact-us" element={<Contact />} />
    </Routes>
  </BrowserRouter>
);

```

Let's use the `/teams/firebirds` URL as an example again. `<Routes>` will match the [location](#location) to your [route config](#route-config), get a set of [matches](#match), and then render a React element tree like this:



```
<App>
  <Teams>
    <Team />
  </Teams>
</App>

```

Each match rendered inside the parent route's element is a really powerful abstraction. Most websites and apps share this characteristic: boxes inside of boxes inside of boxes, each with a navigation section that changes a child section of the page.


### 
Outlets


This nested element tree won't happen automatically. `<Routes>` will render the first match's element for you (In our case that's `<App/>`). The next match's element is `<Teams>`. In order to render that, `App` needs to render an [outlet](#outlet).



```
function App() {
  return (
    <div>
      <GlobalNav />
      <Outlet />
      <GlobalFooter />
    </div>
  );
}

```

The `Outlet` component will always render the next match. That means `<Teams>` also needs an outlet to render `<Team/>`.


If the URL were `/contact-us`, the element tree would change to:



```
<ContactForm />

```

Because the contact form is not under the main `<App>` route.


If the URL were `/teams/firebirds/edit`, the element tree would change to:



```
<App>
  <Teams>
    <EditTeam />
  </Teams>
</App>

```

The outlet swaps out the child for the new child that matches, but the parent layout persists. It's subtle but very effective at cleaning up your components.


### 
Index Routes


Remember the [route config](#route-config) for `/teams`:



```
<Route path="teams" element={<Teams />}>
  <Route path=":teamId" element={<Team />} />
  <Route path="new" element={<NewTeamForm />} />
  <Route index element={<LeagueStandings />} />
</Route>

```

If the URL were `/teams/firebirds`, the element tree would be:



```
<App>
  <Teams>
    <Team />
  </Teams>
</App>

```

But if the URL were `/teams`, the element tree would be:



```
<App>
  <Teams>
    <LeagueStandings />
  </Teams>
</App>

```

League standings? How the heck did `<Route index element={<LeagueStandings>}/>` pop in there? It doesn't even have a path! The reason is that it's an [index route](#index-route). Index routes render in their parent route's [outlet](#outlet) at the parent route's path.


Think of it this way, if you're not at one of the child routes' paths, the `<Outlet>` will render nothing in the UI:



```
<App>
  <Teams />
</App>

```

If all the teams are in a list on the left then an empty outlet means you've got a blank page on the right! Your UI needs something to fill the space: index routes to the rescue.


Another way to think of an index route is that it's the default child route when the parent matches but none of its children do.


Depending on the user interface, you might not need an index route, but if there is any sort of persistent navigation in the parent route you'll most likely want index route to fill the space when the user hasn't clicked one of the items yet.


### 
Layout Routes


Here's a part of our route config we haven't matched yet: `/privacy`. Let's look at the route config again, highlighting the matched routes:



```
<Routes>
  <Route path="/" element={<App />}>
    <Route index element={<Home />} />
    <Route path="teams" element={<Teams />}>
      <Route path=":teamId" element={<Team />} />
      <Route path=":teamId/edit" element={<EditTeam />} />
      <Route path="new" element={<NewTeamForm />} />
      <Route index element={<LeagueStandings />} />
    </Route>
  </Route>
  <Route element={<PageLayout />}>
    <Route path="/privacy" element={<Privacy />} />
    <Route path="/tos" element={<Tos />} />
  </Route>
  <Route path="contact-us" element={<Contact />} />
</Routes>

```

And the resulting element tree rendered will be:



```
<PageLayout>
  <Privacy />
</PageLayout>

```

The `PageLayout` route is admittedly weird. We call it a [layout route](#layout-route) because it doesn't participate in the matching at all (though its children do). It only exists to make wrapping multiple child routes in the same layout simpler. If we didn't allow this then you'd have to handle layouts in two different ways: sometimes your routes do it for you, sometimes you do it manually with lots of layout component repetition throughout your app:


You can do it like this, but we recommend using a layout route



```
<Routes>
  <Route path="/" element={<App />}>
    <Route index element={<Home />} />
    <Route path="teams" element={<Teams />}>
      <Route path=":teamId" element={<Team />} />
      <Route path=":teamId/edit" element={<EditTeam />} />
      <Route path="new" element={<NewTeamForm />} />
      <Route index element={<LeagueStandings />} />
    </Route>
  </Route>
  <Route
    path="/privacy"
    element={
      <PageLayout>
        <Privacy />
      </PageLayout>
    }
  />
  <Route
    path="/tos"
    element={
      <PageLayout>
        <Tos />
      </PageLayout>
    }
  />
  <Route path="contact-us" element={<Contact />} />
</Routes>

```

So, yeah, the semantics of a layout "route" is a bit silly since it has nothing to do with the URL matching, but it's just too convenient to disallow.



Navigating
-----------


When the [URL](#url) changes we call that a "navigation". There are two ways to navigate in React Router:


* `<Link>`
* `navigate`


### 
Link


This is the primary means of navigation. Rendering a `<Link>` allows the user to change the URL when they click it. React Router will prevent the browser's default behavior and tell the [history](#history) to push a new entry into the [history stack](#history-stack). The [location](#location) changes and the new [matches](#match) will render.


However, links are accessible in that they:


* Still render a `<a href>` so all default accessibility concerns are met (like keyboard, focusability, SEO, etc.)
* Don't prevent the browser's default behavior if it's a right click or command/control click to "open in new tab"


[Nested routes](#nested-routes) aren't just about rendering layouts; they also enable "relative links". Consider our `teams` route from before:



```
<Route path="teams" element={<Teams />}>
  <Route path=":teamId" element={<Team />} />
</Route>

```

The `<Teams>` component can render links like:



```
<Link to="psg" />
<Link to="new" />

```

The full path it links to will be `/teams/psg` and `/teams/new`. They inherit the route within which they are rendered. This makes it so your route components don't have to really know anything about the rest of the routes in the app. A very large amount of links just go one more [segment](#segment) deeper. You can rearrange your whole [route config](#route-config) and these links will likely still work just fine. This is very valuable when building out a site in the beginning and the designs and layouts are shifting around.


### 
Navigate Function


This function is returned from the `useNavigate` hook and allows you, the programmer, to change the URL whenever you want. You could do it on a timeout:



```
let navigate = useNavigate();
useEffect(() => {
  setTimeout(() => {
    navigate("/logout");
  }, 30000);
}, []);

```

Or after a form is submitted:



```
<form onSubmit={event => {
  event.preventDefault();
  let data = new FormData(event.target)
  let urlEncoded = new URLSearchParams(data)
  navigate("/create", { state: urlEncoded })
}}>

```

Like `Link`, `navigate` works with nested "to" values as well.



```
navigate("psg");

```

You should have a good reason to use `navigate` instead of `<Link>`. This makes us very sad:



```
<li onClick={() => navigate("/somewhere")} />

```

Aside from links and forms, very few interactions should change the URL because it introduces complexity around accessibility and user expectations.



Data Access
------------


Finally, an application is going to want to ask React Router for a few pieces of information in order to build out the full UI. For this, React Router has a pile of hooks



```
let location = useLocation();
let urlParams = useParams();
let [urlSearchParams] = useSearchParams();

```


Review
-------


Let's put it all together from the top!


1. You render your app:

 
```
const root = ReactDOM.createRoot(
  document.getElementById("root")
);
root.render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<App />}>
        <Route index element={<Home />} />
        <Route path="teams" element={<Teams />}>
          <Route path=":teamId" element={<Team />} />
          <Route path="new" element={<NewTeamForm />} />
          <Route index element={<LeagueStandings />} />
        </Route>
      </Route>
      <Route element={<PageLayout />}>
        <Route path="/privacy" element={<Privacy />} />
        <Route path="/tos" element={<Tos />} />
      </Route>
      <Route path="contact-us" element={<Contact />} />
    </Routes>
  </BrowserRouter>
);

```
2. `<BrowserRouter>` creates a [history](#history), puts the initial [location](#location) in to state, and subscribes to the [URL](#url).
3. `<Routes>` recurses its [child routes](#child-route) to build a [route config](#route-config), matches those routes against the [location](#location), creates some route [matches](#match), and renders the first match's route element.
4. You render an [`<Outlet/>`](#outlet) in each [parent route](#parent-route).
5. The outlets render the next match in the route [matches](#match).
6. The user clicks a link
7. The link calls `navigate()`
8. The [history](#history) changes the URL and notifies `<BrowserRouter>`.
9. `<BrowserRouter>` rerenders, start over at (2)!


That's it! We hope this guide has helped you gain a deeper understanding of the main concepts in React Router.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/start/concepts>

`<Form>`
=========


The Form component is a wrapper around a plain HTML [form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) that emulates the browser for client side routing and data mutations. It is *not* a form validation/state management library like you might be used to in the React ecosystem (for that, we recommend the browser's built in [HTML Form Validation](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation) and data validation on your backend server).



```
import { Form } from "react-router-dom";

function NewEvent() {
  return (
    <Form method="post" action="/events">
      <input type="text" name="title" />
      <input type="text" name="description" />
      <button type="submit">Create</button>
    </Form>
  );
}

```

Make sure your inputs have names or else the `FormData` will not include that field's value.


All of this will trigger state updates to any rendered [`useNavigation`](../hooks/use-navigation) hooks so you can build pending indicators and optimistic UI while the async operations are in-flight.


If the form doesn't *feel* like navigation, you probably want [`useFetcher`](../hooks/use-fetcher).



`action`
---------


The url to which the form will be submitted, just like [HTML form action](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-action). The only difference is the default action. With HTML forms, it defaults to the full URL. With `<Form>`, it defaults to the relative URL of the closest route in context.


Consider the following routes and components:



```
function ProjectsLayout() {
  return (
    <>
      <Form method="post" />
      <Outlet />
    </>
  );
}

function ProjectsPage() {
  return <Form method="post" />;
}

<DataBrowserRouter>
  <Route
    path="/projects"
    element={<ProjectsLayout />}
    action={ProjectsLayout.action}
  >
    <Route
      path=":projectId"
      element={<ProjectPage />}
      action={ProjectsPage.action}
    />
  </Route>
</DataBrowserRouter>;

```

If the the current URL is `"/projects/123"`, the form inside the child route, `ProjectsPage`, will have a default action as you might expect: `"/projects/123"`. In this case, where the route is the deepest matching route, both `<Form>` and plain HTML forms have the same result.


But the form inside of `ProjectsLayout` will point to `"/projects"`, not the full URL. In other words, it points to the matching segment of the URL for the route in which the form is rendered.


This helps with portability as well as co-location of forms and their action handlers when if you add some convention around your route modules.


If you need to post to a different route, then add an action prop:



```
<Form action="/projects/new" method="post" />

```

**See also:**


* [Index Search Param](../guides/index-search-param) (index vs parent route disambiguation)



`method`
---------


This determines the [HTTP verb](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) to be used. The same as plain HTML [form method](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-method), except it also supports "put", "patch", and "delete" in addition to "get" and "post". The default is "get".


### 
GET submissions


The default method is "get". Get submissions *will not call an action*. Get submissions are the same as a normal navigation (user clicks a link) except the user gets to supply the search params that go to the URL from the form.



```
<Form method="get" action="/products">
  <input
    aria-label="search products"
    type="text"
    name="q"
  />
  <button type="submit">Search</button>
</Form>

```

Let's say the user types in "running shoes" and submits the form. React Router emulates the browser and will serialize the form into [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) and then navigate the user to `"/products?q=running+shoes"`. It's as if you rendered a `<Link to="/products?q=running+shoes">` as the developer, but instead you let the user supply the query string dynamically.


Your route loader can access these values most conveniently by creating a new [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) from the `request.url` and then load the data.



```
<Route
  path="/products"
  loader={async ({ request }) => {
    let url = new URL(request.url);
    let searchTerm = url.searchParams.get("q");
    return fakeSearchProducts(searchTerm);
  }}
/>

```

### 
Mutation Submissions


All other methods are "mutation submissions", meaning you intend to change something about your data with POST, PUT, PATCH, or DELETE. Note that plain HTML forms only support "post" and "get", we tend to stick to those two as well.


When the user submits the form, React Router will match the `action` to the app's routes and call the `<Route action>` with the serialized [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData). When the action completes, all of the loader data on the page will automatically revalidate to keep your UI in sync with your data.


The method will be available on [`request.method`](https://developer.mozilla.org/en-US/docs/Web/API/Request/method) inside the route action that is called. You can use this to instruct your data abstractions about the intent of the submission.



```
<Route
  path="/projects/:id"
  element={<Project />}
  loader={async ({ params }) => {
    return fakeLoadProject(params.id)
  }}
  action={async ({ request, params }) => {
    switch (request.method) {
      case "put": {
        let formData = await request.formData();
        let name = formData.get("projectName");
        return fakeUpdateProject(name);
      }
      case "delete": {
        return fakeDeleteProject(params.id);
      }
      default {
        throw new Response("", { status: 405 })
      }
    }
  }}
/>;

function Project() {
  let project = useLoaderData();

  return (
    <>
      <Form method="put">
        <input
          type="text"
          name="projectName"
          defaultValue={project.name}
        />
        <button type="submit">Update Project</button>
      </Form>

      <Form method="delete">
        <button type="submit">Delete Project</button>
      </Form>
    </>
  );
}

```

As you can see, both forms submit to the same route but you can use the `request.method` to branch on what you intend to do. After the actions completes, the `loader` will be revalidated and the UI will automatically synchronize with the new data.



`replace`
----------


Instructs the form to replace the current entry in the history stack, instead of pushing the new entry.



```
<Form replace />

```

The default behavior is conditional on the form `method`:


* `get` defaults to `false`
* every other method defaults to `true` if your `action` is successful
* if your `action` redirects or throws, then it will still push by default


We've found with `get` you often want the user to be able to click "back" to see the previous search results/filters, etc. But with the other methods the default is `true` to avoid the "are you sure you want to resubmit the form?" prompt. Note that even if `replace={false}` React Router *will not* resubmit the form when the back button is clicked and the method is post, put, patch, or delete.


In other words, this is really only useful for GET submissions and you want to avoid the back button showing the previous results.



`relative`
-----------


By default, paths are relative to the route hierarchy, so `..` will go up one `Route` level. Occasionally, you may find that you have matching URL patterns that do not make sense to be nested, and you're prefer to use relative *path* routing. You can opt into this behavior with `<Form to="../some/where" relative="path">`



`reloadDocument`
-----------------


Instructs the form to skip React Router and submit the form with the browser's built in behavior.



```
<Form reloadDocument />

```

This is recommended over `<form>` so you can get the benefits of default and relative `action`, but otherwise is the same as a plain HTML form.


Without a framework like [Remix](https://remix.run), or your own server handling of posts to routes, this isn't very useful.


See also:


* [`useNavigation`](../hooks/use-navigation)
* [`useActionData`](../hooks/use-action-data)
* [`useSubmit`](../hooks/use-submit)



Examples
=========


TODO: More examples



Large List Filtering
---------------------


A common use case for GET submissions is filtering a large list, like ecommerce and travel booking sites.



```
function FilterForm() {
  return (
    <Form method="get" action="/slc/hotels">
      <select name="sort">
        <option value="price">Price</option>
        <option value="stars">Stars</option>
        <option value="distance">Distance</option>
      </select>

      <fieldset>
        <legend>Star Rating</legend>
        <label>
          <input type="radio" name="stars" value="5" />{" "}
          ★★★★★
        </label>
        <label>
          <input type="radio" name="stars" value="4" /> ★★★★
        </label>
        <label>
          <input type="radio" name="stars" value="3" /> ★★★
        </label>
        <label>
          <input type="radio" name="stars" value="2" /> ★★
        </label>
        <label>
          <input type="radio" name="stars" value="1" /> ★
        </label>
      </fieldset>

      <fieldset>
        <legend>Amenities</legend>
        <label>
          <input
            type="checkbox"
            name="amenities"
            value="pool"
          />{" "}
          Pool
        </label>
        <label>
          <input
            type="checkbox"
            name="amenities"
            value="exercise"
          />{" "}
          Exercise Room
        </label>
      </fieldset>
      <button type="submit">Search</button>
    </Form>
  );
}

```

When the user submits this form, the form will be serialized to the URL with something like this, depending on the user's selections:


You can access those values from the `request.url`



```
<Route
  path="/:city/hotels"
  loader={async ({ request }) => {
    let url = new URL(request.url);
    let sort = url.searchParams.get("sort");
    let stars = url.searchParams.get("stars");
    let amenities = url.searchParams.getAll("amenities");
    return fakeGetHotels({ sort, stars, amenities });
  }}
/>

```

**See also:**


* [useSubmit](../hooks/use-submit)



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/components/form>

Scroll Restoration
===================


This example demonstrates the basic usage of the `<ScrollRestoration>` component, including:


* Restoring scroll position via `location.key`
* Restoring scroll position via `location.pathname`
* Preventing scroll resetting via `<Link>`



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/scroll-restoration>

`errorElement`
===============


When exceptions are thrown in [loaders](loader), [actions](action), or component rendering, instead of the normal render path for your Routes (`<Route element>`), the error path will be rendered (`<Route errorElement>`) and the error made available with [`useRouteError`](../hooks/use-route-error).


This feature only works if using a data router like [`createBrowserRouter`](../routers/create-browser-router)



```
<Route
  path="/invoices/:id"
  // if an exception is thrown here
  loader={loadInvoice}
  // here
  action={updateInvoice}
  // or here
  element={<Invoice />}
  // this will render instead of `element`
  errorElement={<ErrorBoundary />}
/>;

function Invoice() {
  return <div>Happy {path}</div>;
}

function ErrorBoundary() {
  let error = useRouteError();
  console.error(error);
  // Uncaught ReferenceError: path is not defined
  return <div>Dang!</div>;
}

```


Bubbling
---------


When a route does not have an `errorElement`, errors will bubble up through parent routes. This lets you get as granular or general as you like.


Put an `errorElement` at the top of your route tree and handle nearly every error in your app in one place. Or, put them on all of your routes and allow the parts of the app that don't have errors to continue to render normally. This gives the user more options to recover from errors instead of a hard refresh and 🤞.



Throwing Manually
------------------


While `errorElement` handles unexpected errors, it can also be used to handle exceptions you expect.


Particularly in loaders and actions, where you work with external data not in your control, you can't always plan on the data existing, the service being available, or the user having access to it. In these cases you can `throw` your own exceptions.


Here's a "not found" case in a <loader>:



```
<Route
  path="/properties/:id"
  element={<PropertyForSale />}
  errorElement={<PropertyError />}
  loader={async ({ params }) => {
    const res = await fetch(`/api/properties/${params.id}`);
    if (res.status === 404) {
      throw new Response("Not Found", { status: 404 });
    }
    const home = res.json();
    const descriptionHtml = parseMarkdown(
      data.descriptionMarkdown
    );
    return { home, descriptionHtml };
  }}
/>

```

As soon as you know you can't render the route with the data you're loading, you can throw to break the call stack. You don't have to worry about the rest of the work in the loader (like parsing the user's markdown bio) when it doesn't exist. Just throw and get out of there.


This also means you don't have to worry about a bunch of error branching code in your route component, it won't even try to render if you throw in the loader or action, instead your `errorElement` will render.


You can throw anything from a loader or action just like you can return anything: responses (like the previous example), errors, or plain objects.



Throwing Responses
-------------------


While you can throw anything and it will be provided back to you through [`useRouteError`](../hooks/use-route-error), If you throw a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response), React Router will automatically parse the response data before returning it to your components.


Additionally, [`isRouteErrorResponse`](../utils/is-route-error-response) lets you check for this specific type in your boundaries. Coupled with [`json`](../fetch/json), you can easily throw responses with some data and render different cases in your boundary:



```
import { json } from "react-router-dom";

function loader() {
  const stillWorksHere = await userStillWorksHere();
  if (!stillWorksHere) {
    throw json(
      {
        sorry: "You have been fired.",
        hrEmail: "hr@bigco.com",
      },
      { status: 401 }
    );
  }
}

function ErrorBoundary() {
  const error = useRouteError();

  if (isRouteErrorResponse(error) && error.status === 401) {
    // the response json is automatically parsed to
    // `error.data`, you also have access to the status
    return (
      <div>
        <h1>{error.status}</h1>
        <h2>{error.data.sorry}</h2>
        <p>
          Go ahead and email {error.data.hrEmail} if you
          feel like this is a mistake.
        </p>
      </div>
    );
  }

  // rethrow to let the parent error boundary handle it
  // when it's not a special case for this route
  throw error;
}

```

This makes it possible to create a general error boundary, usually on your root route, that handles many cases:



```
function RootBoundary() {
  const error = useRouteError();

  if (isRouteErrorResponse(error)) {
    if (error.status === 404) {
      return <div>This page doesn't exist!</div>;
    }

    if (error.status === 401) {
      return <div>You aren't authorized to see this</div>;
    }

    if (error.status === 503) {
      return <div>Looks like our API is down</div>;
    }

    if (error.status === 418) {
      return <div>🫖</div>;
    }
  }

  return <div>Something went wrong</div>;
}

```


Abstractions
-------------


This pattern of throwing when you know you can't continue down the data loading path you're on makes it pretty simple to properly handle exceptional situations.


Imagine a function that gets the user's web token for authorized requests looking something like this:



```
async function getUserToken() {
  const token = await getTokenFromWebWorker();
  if (!token) {
    throw new Response("", { status: 401 });
  }
  return token;
}

```

No matter which loader or action uses that function, it will stop executing code in the current call stack and send the app over to the error path instead.


Now let's add a function that fetches a project:



```
function fetchProject(id) {
  const token = await getUserToken();
  const response = await fetch(`/projects/${id}`, {
    headers: { Authorization: `Bearer ${token}` },
  });

  if (res.status === 404) {
    throw new Response("Not Found", { status: 404 });
  }

  // the fetch failed
  if (!res.ok) {
    throw new Error("Could not fetch project");
  }
}

```

Thanks to `getUserToken`, this code can assume it gets a token. If there isn't one, the error path will be rendered. Then if the project doesn't exist, no matter which loader is calling this function, it will throw a 404 over to the `errorElement`. Finally, if the fetch fails completely, it will send an error.


At any time you realize "I don't have what I need", you can simply `throw`, knowing that you're still rendering something useful for the end user.


Let's put it together into a route:



```
<Route
  path="/"
  element={<Root />}
  errorElement={<RootBoundary />}
>
  <Route
    path="projects/:projectId"
    loader={({ params }) => fetchProject(params.projectId)}
    element={<Project />}
  />
</Route>

```

The project route doesn't have to think about errors at all. Between the loader utility functions like `fetchProject` and `getUserToken` throwing whenever something isn't right, and the `RootBoundary` handling all of the cases, the project route gets to focus strictly on the happy path.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/route/error-element>

Custom Filter Link Example
===========================


This example demonstrates how to use a query string parameter to mark a link as "active" or not. This is a common technique when implementing a filter in a sidebar where you're browsing products.



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/custom-filter-link>

Modal Example
==============



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/modal>

Custom Query Parsing Example
=============================


This example demonstrates how to store a complex data structure in the URL query string using a custom hook.


It's a good example of how React Router's low-level hooks provide you with all the flexibility you need to create your own custom hooks that fit the needs of your app.



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/custom-query-parsing>

Multi App Example
==================


This example demonstrates how to build a site with multiple React Router apps by mounting each at a URL pathname prefix using the `<Router basename>` prop. This essentially decouples the apps from each other and allows them to be portable and even deployed separately.



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/multi-app>

Search Params Example
======================


This example demonstrates how to read and write the URL query string using the `useSearchParams()` hook. This hook is similar to the `useNavigate()` hook, but just for the [`search` portion of the URL](https://developer.mozilla.org/en-US/docs/Web/API/Location/search).


In this example, we have a form to search for a user on GitHub and display their user profile.



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/search-params>

Server-side Rendering Example
==============================


This example adds [server-side rendering](https://reactjs.org/docs/react-dom-server.html) (SSR) to our basic example.


With SSR, the server renders your app and sends real HTML to the browser instead of an empty HTML document with a bunch of `<script>` tags. After the browser loads the HTML and JavaScript from the server, React "hydrates" the HTML document using the same components it used to render the app on the server.


This example contains a server (see [server.js](https://github.com/remix-run/react-router/blob/main/examples/ssr/server.js)) that can run in both development and production modes.


In the browser entry point (see [src/entry.client.tsx](https://github.com/remix-run/react-router/blob/main/examples/ssr/src/entry.client.tsx)), we use React Router like we would traditionally do in a purely client-side app and render a `<BrowserRouter>` to provide routing context to the rest of the app. The main difference is that instead of using `ReactDOM.createRoot(el).render()` to render the app, since the HTML was already sent by the server, all we need is `ReactDOM.hydrateRoot()`.


On the server (see [src/entry.server.tsx](https://github.com/remix-run/react-router/blob/main/examples/ssr/src/entry.server.tsx)), we use React Router's `<StaticRouter>` to render the app and plug in the URL we get from the incoming HTTP request.



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/ssr>

Custom Link Example
====================


This example demonstrates how to make a custom `<Link>` component to render something different when the link is "active" using the `useMatch()` and `useResolvedPath()` hooks.



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/custom-link>

Route Objects Example
======================


This example demonstrates how to use the `useRoutes()` hook to define and render routes using regular JavaScript objects instead of `<Routes>` and `<Route>` elements. This is mainly a stylistic preference that may make more sense in some scenarios, depending on the data structures you're working with to define your routes.


One interesting thing to note is that even if you don't use this hook directly, `<Routes>` uses it internally. So either way you're using the exact same code path!



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/route-objects>

`useFormAction`
================


 Type declaration
```
declare function useFormAction(
  action?: string,
  { relative }: { relative?: RelativeRoutingType } = {}
): string;

```
This hook is used internally in [`<Form>`](../components/form) to automatically resolve default and relative actions to the current route in context. While uncommon, you can use it directly to do things like compute the correct action for a `<button formAction>` to change the action of the button's `<Form>`. (Yes, HTML buttons can change the action of their form!)



```
import { useFormAction } from "react-router-dom";

function DeleteButton() {
  return (
    <button
      formAction={useFormAction("destroy")}
      formMethod="post"
    >
      Delete
    </button>
  );
}

```

It's also useful for automatically resolving the action for [`submit`](use-submit) and [`fetcher.submit`](use-fetcher#fetchersubmit).



```
let submit = useSubmit();
let action = useFormAction();
submit(formData, { action });

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-form-action>

`useAsyncError`
================


Returns the rejection value from the nearest [`<Await>`][await] component.



```
import { useAsyncError, Await } from "react-router-dom";

function ErrorElement() {
  const error = useAsyncError();
  return (
    <p>Uh Oh, something went wrong! {error.message}</p>
  );
}

<Await
  resolve={promiseThatRejects}
  errorElement={<ErrorElement />}
/>;

```

See the [Deferred Data Guide](../guides/deferred) and [`<Await>` docs](../components/await) for more information.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-async-error>

`useHref`
==========


 Type declaration
```
declare function useHref(
  to: To,
  options?: { relative?: RelativeRoutingType }
): string;

```
The `useHref` hook returns a URL that may be used to link to the given `to` location, even outside of React Router.



>  **Tip:**
> 
>  You may be interested in taking a look at the source for the `<Link>` component in `react-router-dom` to see how it uses `useHref` internally to determine its own `href` value.
> 
>  



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-href>

`useMatch`
===========


 Type declaration
```
declare function useMatch<
  ParamKey extends ParamParseKey<Path>,
  Path extends string
>(
  pattern: PathPattern<Path> | Path
): PathMatch<ParamKey> | null;

```
Returns match data about a route at the given path relative to the current location.


See [`matchPath`](../utils/match-path) for more information.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-match>

`useFetcher`
=============


In HTML/HTTP, data mutations and loads are modeled with navigation: `<a href>` and `<form action>`. Both cause a navigation in the browser. The React Router equivalents are [`<Link>`](../components/link) and [`<Form>`](../components/form).


But sometimes you want to call a loader outside of navigation, or call an action (and get the data on the page to revalidate) without changing the URL. Or you need to have multiple mutations in-flight at the same time.


Many interactions with the server aren't navigation events. This hook lets you plug your UI into your actions and loaders without navigating.


This is useful when you need to:


* fetch data not associated with UI routes (popovers, dynamic forms, etc.)
* submit data to actions without navigating (shared components like a newsletter sign ups)
* handle multiple concurrent submissions in a list (typical "todo app" list where you can click multiple buttons and all should be pending at the same time)
* infinite scroll containers
* and more!


If you're building a highly interactive, "app like" user interface, you will `useFetcher` often.



```
import { useFetcher } from "react-router-dom";

function SomeComponent() {
  const fetcher = useFetcher();

  // call submit or load in a useEffect
  React.useEffect(() => {
    fetcher.submit(data, options);
    fetcher.load(href);
  }, [fetcher]);

  // build your UI with these properties
  fetcher.state;
  fetcher.formData;
  fetcher.formMethod;
  fetcher.formAction;
  fetcher.data;

  // render a form that doesn't cause navigation
  return <fetcher.Form />;
}

```

Fetchers have a lot of built-in behavior:


* Automatically handles cancellation on interruptions of the fetch
* When submitting with POST, PUT, PATCH, DELETE, the action is called first
	+ After the action completes, the data on the page is revalidated to capture any mutations that may have happened, automatically keeping your UI in sync with your server state
* When multiple fetchers are inflight at once, it will
	+ commit the freshest available data as they each land
	+ ensure no stale loads override fresher data, no matter which order the responses return
* Handles uncaught errors by rendering the nearest `errorElement` (just like a normal navigation from `<Link>` or `<Form>`)
* Will redirect the app if your action/loader being called returns a redirect (just like a normal navigation from `<Link>` or `<Form>`)



`fetcher.state`
----------------


You can know the state of the fetcher with `fetcher.state`. It will be one of:


* **idle** - nothing is being fetched.
* **submitting** - A route action is being called due to a fetcher submission using POST, PUT, PATCH, or DELETE
* **loading** - The fetcher is calling a loader (from a `fetcher.load`) or is being revalidated after a separate submission or `useRevalidator` call



`fetcher.Form`
---------------


Just like `<Form>` except it doesn't cause a navigation. (You'll get over the dot in JSX ... we hope!)



```
function SomeComponent() {
  const fetcher = useFetcher();
  return (
    <fetcher.Form method="post" action="/some/route">
      <input type="text" />
    </fetcher.Form>
  );
}

```


`fetcher.load()`
-----------------


Loads data from a route loader.



```
import { useFetcher } from "react-router-dom";

function SomeComponent() {
  const fetcher = useFetcher();

  useEffect(() => {
    if (fetcher.state === "idle" && !fetcher.data) {
      fetcher.load("/some/route");
    }
  }, [fetcher]);

  return <div>{fetcher.data || "Loading..."}</div>;
}

```

Although a URL might match multiple nested routes, a `fetcher.load()` call will only call the loader on the leaf match (or parent of [index routes](../guides/index-search-param)).


If you find yourself calling this function inside of click handlers, you can probably simplify your code by using `<fetcher.Form>` instead.


Any `fetcher.load` calls that are active on the page will be re-executed as part of revalidation (either after a navigation submission, another fetcher submission, or a `useRevalidator()` call)



`fetcher.submit()`
-------------------


The imperative version of `<fetcher.Form>`. If a user interaction should initiate the fetch, you should use `<fetcher.Form>`. But if you, the programmer are initiating the fetch (not in response to a user clicking a button, etc.), then use this function.


For example, you may want to log the user out after a certain amount of idle time:



```
import { useFetcher } from "react-router-dom";
import { useFakeUserIsIdle } from "./fake/hooks";

export function useIdleLogout() {
  const fetcher = useFetcher();
  const userIsIdle = useFakeUserIsIdle();

  useEffect(() => {
    if (userIsIdle) {
      fetcher.submit(
        { idle: true },
        { method: "post", action: "/logout" }
      );
    }
  }, [userIsIdle]);
}

```

If you want to submit to an index route, use the [`?index` param](../guides/index-search-param).


If you find yourself calling this function inside of click handlers, you can probably simplify your code by using `<fetcher.Form>` instead.



`fetcher.data`
---------------


The returned data from the loader or action is stored here. Once the data is set, it persists on the fetcher even through reloads and resubmissions.



```
function ProductDetails({ product }) {
  const fetcher = useFetcher();

  return (
    <details
      onToggle={(event) => {
        if (
          event.currentTarget.open &&
          fetcher.state === "idle" &&
          !fetcher.data
        ) {
          fetcher.load(`/product/${product.id}/details`);
        }
      }}
    >
      <summary>{product.name}</summary>
      {fetcher.data ? (
        <div>{fetcher.data}</div>
      ) : (
        <div>Loading product details...</div>
      )}
    </details>
  );
}

```


`fetcher.formData`
-------------------


When using `<fetcher.Form>` or `fetcher.submit()`, the form data is available to build optimistic UI.



```
function TaskCheckbox({ task }) {
  let fetcher = useFetcher();

  // while data is in flight, use that to immediately render
  // the state you expect the task to be in when the form
  // submission completes, instead of waiting for the
  // network to respond. When the network responds, the
  // formData will no longer be available and the UI will
  // use the value in `task.status` from the revalidation
  let status =
    fetcher.formData?.get("status") || task.status;

  let isComplete = status === "complete";

  return (
    <fetcher.Form method="post">
      <button
        type="submit"
        name="status"
        value={isComplete ? "incomplete" : "complete"}
      >
        {isComplete ? "Mark Incomplete" : "Mark Complete"}
      </button>
    </fetcher.Form>
  );
}

```


`fetcher.formAction`
---------------------


Tells you the action url the form is being submitted to.



```
<fetcher.Form action="/mark-as-read" />;

// when the form is submitting
fetcher.formAction; // "mark-as-read"

```


`fetcher.formMethod`
---------------------


Tells you the method of the form being submitted: get, post, put, patch, or delete.



```
<fetcher.Form method="post" />;

// when the form is submitting
fetcher.formMethod; // "post"

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-fetcher>

`useFetchers`
==============


Returns an array of all inflight [fetchers](use-fetcher) without their `load`, `submit`, or `Form` properties (can't have parent components trying to control the behavior of their children! We know from IRL experience that this is a fool's errand.)



```
import { useFetchers } from "react-router-dom";

function SomeComp() {
  const fetchers = useFetchers();
  // array of inflight fetchers
}

```

This is useful for components throughout the app that didn't create the fetchers but want to use their submissions to participate in optimistic UI.


For example, imagine a UI where the sidebar lists projects, and the main view displays a list of checkboxes for the current project. The sidebar could display the number of completed and total tasks for each project.


When the user clicks a checkbox, the submission goes to the action to change the state of the task. Instead of creating a "loading state" we want to create an "optimistic UI" that will **immediately** update the checkbox to appear checked even though the server hasn't processed it yet. In the checkbox component, we can use `fetcher.submission`:



```
function Task({ task }) {
  const { projectId, id } = task;
  const toggle = useFetcher();
  const checked =
    toggle.formData?.get("complete") || task.complete;

  return (
    <toggle.Form
      method="put"
      action={`/project/${projectId}/tasks/${id}`}
    >
      <label>
        <input
          type="checkbox"
          checked={checked}
          onChange={(e) => toggle.submit(e.target.form)}
        />
      </label>
    </toggle.Form>
  );
}

```

This awesome for the checkbox, but the sidebar will say 2/4 while the checkboxes show 3/4 when the user clicks on of them!


Because routes are automatically revalidated, the sidebar will quickly update and be correct. But for a moment, it's gonna feel a little funny.


This is where `useFetchers` comes in. Up in the sidebar, we can access all the inflight fetcher states from the checkboxes - even though it's not the component that created them.


The strategy has three steps:


1. Find the submissions for tasks in a specific project
2. Use the `fetcher.formData` to immediately update the count
3. Use the normal task's state if it's not inflight



```
function ProjectTaskCount({ project }) {
  let completedTasks = 0;
  const fetchers = useFetchers();

  // Find this project's fetchers
  let projectFetchers = fetchers.filter((fetcher) => {
    return fetcher.formAction?.startsWith(
      `/projects/${project.id}/task`
    );
  });

  // Store in a map for easy lookup
  const myFetchers = new Map(
    fetchers.map(({ formData }) => [
      formData.get("id"),
      formData.get("complete") === "on",
    ])
  );

  // Increment the count
  for (const task of project.tasks) {
    if (myFetchers.has(task.id)) {
      if (myFetchers.get(task.id)) {
        // if it's being submitted, increment optimistically
        completedTasks++;
      }
    } else if (task.complete) {
      // otherwise use the real task's data
      completedTasks++;
    }
  }

  return (
    <small>
      {completedTasks}/{project.tasks.length}
    </small>
  );
}

```

It's a little bit of work, but it's mostly just asking React Router for the state it's tracking and doing an optimistic calculation based on it.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-fetchers>

Data Router Server-side Rendering Example
==========================================


This example adds [server-side rendering](https://reactjs.org/docs/react-dom-server.html) (SSR) to our basic example using a data router.


With SSR, the server renders your app and sends real HTML to the browser instead of an empty HTML document with a bunch of `<script>` tags. After the browser loads the HTML and JavaScript from the server, React "hydrates" the HTML document using the same components it used to render the app on the server.


This example contains a server (see [server.js](https://github.com/remix-run/react-router/blob/main/examples/ssr-data-router/server.js)) that can run in both development and production modes.


In the browser entry point (see [src/entry.client.tsx](https://github.com/remix-run/react-router/blob/main/examples/ssr-data-router/src/entry.client.tsx)), we use React Router like we would traditionally do in a purely client-side app and render a `<DataBrowserRouter>` to provide routing context to the rest of the app. The main difference is that instead of using `ReactDOM.createRoot(el).render()` to render the app, since the HTML was already sent by the server, all we need is `ReactDOM.hydrateRoot()`.


On the server (see [src/entry.server.tsx](https://github.com/remix-run/react-router/blob/main/examples/ssr-data-router/src/entry.server.tsx)), we create a static request handler using `createStaticHandler` and query for the incoming `Request` we get from Express (note that we convert the Express request to a Web Fetch Request). Once the router is finished with data loading, we use React Router's `<unstable_DataStaticRouter>` to render the app in the correct state.



Preview
--------


Open this example on [StackBlitz](https://stackblitz.com):


[![Open in StackBlitz]



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/examples/ssr-data-router>

`useLoaderData`
================


This hook provides the value returned from your route loader.



```
import {
  createBrowserRouter,
  RouterProvider,
  useLoaderData,
} from "react-router-dom";

function loader() {
  return fetchFakeAlbums();
}

export function Albums() {
  const albums = useLoaderData();
  // ...
}

const router = createBrowserRouter([
  {
    path: "/",
    loader: loader,
    element: <Albums />,
  },
]);

ReactDOM.createRoot(el).render(
  <RouterProvider router={router} />
);

```

After route [actions](../components/route#action) are called, the data will be revalidated automatically and return the latest result from your loader.


Note that `useLoaderData` *does not initiate a fetch*. It simply reads the result of a fetch React Router manages internally, so you don't need to worry about it refetching when it re-renders for reasons outside of routing.


This also means data returned is stable between renders, so you can safely pass it to dependency arrays in React hooks like `useEffect`. It only changes when the loader is called again after actions or certain navigations. In these cases the identity will change (even if the values don't).


You can use this hook in any component or any custom hook, not just the Route element. It will return the data from the nearest route on context.


To get data from any active route on the page, see [`useRouteLoaderData`](use-route-loader-data).



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-loader-data>

`useAsyncValue`
================


Returns the resolved data from the nearest `<Await>` ancestor component.



```
function ProductVariants() {
  const variants = useAsyncValue();
  return <div>{/* ... */}</div>;
}

// Await creates the context for the value
<Await resolve={somePromiseForProductVariants}>
  <ProductVariants />
</Await>;

```

See the [Deferred Data Guide](../guides/deferred) and [`<Await>` docs](../components/await) for more information.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-async-value>

`useInRouterContext`
=====================


 Type declaration
```
declare function useInRouterContext(): boolean;

```
The `useInRouterContext` hooks returns `true` if the component is being rendered in the context of a `<Router>`, `false` otherwise. This can be useful for some 3rd-party extensions that need to know if they are being rendered in the context of a React Router app.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-in-router-context>

`useActionData`
================


This hook provides the returned value from the previous navigation's `action` result, or `undefined` if there was no submission.



```
import { useActionData } from "react-router-dom";

function SomeComponent() {
  let actionData = useActionData();
  // ...
}

```

The most common use-case for this hook is form validation errors. If the form isn't right, you can return the errors and let the user try again:



```
import {
  useActionData,
  Form,
  redirect,
} from "react-router-dom";

export default function SignUp() {
  const errors = useActionData();

  return (
    <Form method="post">
      <p>
        <input type="text" name="email" />
        {errors?.email && <span>{errors.email}</span>}
      </p>

      <p>
        <input type="text" name="password" />
        {errors?.password && <span>{errors.password}</span>}
      </p>

      <p>
        <button type="submit">Sign up</button>
      </p>
    </Form>
  );
}

export async function action({ request }) {
  const formData = await request.formData();
  const email = formData.get("email");
  const password = formData.get("password");
  const errors = {};

  // validate the fields
  if (typeof email !== "string" || !email.includes("@")) {
    errors.email =
      "That doesn't look like an email address";
  }

  if (typeof password !== "string" || password.length < 6) {
    errors.password = "Password must be > 6 characters";
  }

  // return data if we have errors
  if (Object.keys(errors).length) {
    return errors;
  }

  // otherwise create the user and redirect
  await createUser(email, password);
  return redirect("/dashboard");
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-action-data>

`useLocation`
==============


 Type declaration
```
declare function useLocation(): Location;

interface Location extends Path {
  state: unknown;
  key: Key;
}

```
This hook returns the current [`location`](../utils/location) object. This can be useful if you'd like to perform some side effect whenever the current location changes.



```
import * as React from 'react';
import { useLocation } from 'react-router-dom';

function App() {
  let location = useLocation();

  React.useEffect(() => {
    // Google Analytics
    ga('send', 'pageview');
  }, [location]);

  return (
    // ...
  );
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-location>

`useNavigation`
================


This hook tells you everything you need to know about a page navigation to build pending navigation indicators and optimistic UI on data mutations. Things like:


* Global loading indicators
* Disabling forms while a mutation is happening
* Adding busy indicators to submit buttons
* Optimistically showing a new record while it's being created on the server
* Optimistically showing the new state of a record while it's being updated



```
import { useNavigation } from "react-router-dom";

function SomeComponent() {
  const navigation = useNavigation();
  navigation.state;
  navigation.location;
  navigation.formData;
  navigation.formAction;
  navigation.formMethod;
}

```


`navigation.state`
-------------------


* **idle** - There is no navigation pending.
* **submitting** - A route action is being called due to a form submission using POST, PUT, PATCH, or DELETE
* **loading** - The loaders for the next routes are being called to render the next page


Normal navigations and GET form submissions transition through these states:


Form submissions with POST, PUT, PATCH, or DELETE transition through these states:


Here's a simple submit button that changes its text when the navigation state is changing:



```
function SubmitButton() {
  const navigation = useNavigation();

  const text =
    navigation.state === "submitting"
      ? "Saving..."
      : navigation.state === "loading"
      ? "Saved!"
      : "Go";

  return <button type="submit">{text}</button>;
}

```

While `navigation.state` provides the high-level state of the active navigation, you can deduce more granular information by combining it with other `navigation` aspects:



```
// Is this just a normal load?
let isNormalLoad =
  navigation.state === "loading" &&
  navigation.formData == null;

// Are we reloading after an action?
let isReloading =
  navigation.state === "loading" &&
  navigation.formData != null &&
  navigation.formAction === navigation.location.pathname;

// Are we redirecting after an action?
let isRedirecting =
  navigation.state === "loading" &&
  navigation.formData != null &&
  navigation.formAction !== navigation.location.pathname;

```


`navigation.formData`
----------------------


Any POST, PUT, PATCH, or DELETE navigation that started from a `<Form>` or `useSubmit` will have your form's submission data attached to it. This is primarily useful to build "Optimistic UI" with the `submission.formData` [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) object.


In the case of a GET form submission, `formData` will be empty and the data will be reflected in `navigation.location.search`.



`navigation.location`
----------------------


This tells you what the next [location](../utils/location) is going to be.


Note that this link will not appear "pending" if a form is being submitted to the URL the link points to, because we only do this for "loading" states. The form will contain the pending UI for when the state is "submitting", once the action is complete, then the link will go pending.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-navigation>

`useNavigate`
==============


It's usually better to use [`redirect`](../fetch/redirect) in loaders and actions than this hook


The `useNavigate` hook returns a function that lets you navigate programmatically, for example in an effect:



```
import { useNavigate } from "react-router-dom";

function useLogoutTimer() {
  const userIsInactive = useFakeInactiveUser();
  const navigate = useNavigate();

  useEffect(() => {
    if (userIsInactive) {
      fake.logout();
      navigate("/session-timed-out");
    }
  }, [userIsInactive]);
}

```


Type Declaration
-----------------



```
declare function useNavigate(): NavigateFunction;

interface NavigateFunction {
  (
    to: To,
    options?: {
      replace?: boolean;
      state?: any;
      relative?: RelativeRoutingType;
    }
  ): void;
  (delta: number): void;
}

```

The `navigate` function has two signatures:


* Either pass a `To` value (same type as `<Link to>`) with an optional second `{ replace, state }` arg or
* Pass the delta you want to go in the history stack. For example, `navigate(-1)` is equivalent to hitting the back button.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-navigate>

`useLinkClickHandler`
======================


 Type declaration
```
declare function useLinkClickHandler<
  E extends Element = HTMLAnchorElement
>(
  to: To,
  options?: {
    target?: React.HTMLAttributeAnchorTarget;
    replace?: boolean;
    state?: any;
    options?: { relative?: RelativeRoutingType };
  }
): (event: React.MouseEvent<E, MouseEvent>) => void;

```
The `useLinkClickHandler` hook returns a click event handler for navigation when building a custom `<Link>` in `react-router-dom`.



```
import {
  useHref,
  useLinkClickHandler,
} from "react-router-dom";

const StyledLink = styled("a", { color: "fuchsia" });

const Link = React.forwardRef(
  (
    {
      onClick,
      replace = false,
      state,
      target,
      to,
      ...rest
    },
    ref
  ) => {
    let href = useHref(to);
    let handleClick = useLinkClickHandler(to, {
      replace,
      state,
      target,
    });

    return (
      <StyledLink
        {...rest}
        href={href}
        onClick={(event) => {
          onClick?.(event);
          if (!event.defaultPrevented) {
            handleClick(event);
          }
        }}
        ref={ref}
        target={target}
      />
    );
  }
);

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-link-click-handler>

`useOutlet`
============


 Type declaration
```
declare function useOutlet(): React.ReactElement | null;

```
Returns the element for the child route at this level of the route hierarchy. This hook is used internally by [`<Outlet>`](../components/outlet) to render child routes.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-outlet>

`useOutletContext`
===================


 Type declaration
```
declare function useOutletContext<
  Context = unknown
>(): Context;

```
Often parent routes manage state or other values you want shared with child routes. You can create your own [context provider](https://reactjs.org/docs/context.html) if you like, but this is such a common situation that it's built-into `<Outlet />`:



```
function Parent() {
  const [count, setCount] = React.useState(0);
  return <Outlet context={[count, setCount]} />;
}

```


```
import { useOutletContext } from "react-router-dom";

function Child() {
  const [count, setCount] = useOutletContext();
  const increment = () => setCount((c) => c + 1);
  return <button onClick={increment}>{count}</button>;
}

```

If you're using TypeScript, we recommend the parent component provide a custom hook for accessing the context value. This makes it easier for consumers to get nice typings, control consumers, and know who's consuming the context value. Here's a more realistic example:



```
import * as React from "react";
import type { User } from "./types";
import { Outlet, useOutletContext } from "react-router-dom";

type ContextType = { user: User | null };

export default function Dashboard() {
  const [user, setUser] = React.useState<User | null>(null);

  return (
    <div>
      <h1>Dashboard</h1>
      <Outlet context={{ user }} />
    </div>
  );
}

export function useUser() {
  return useOutletContext<ContextType>();
}

```


```
import { useUser } from "../dashboard";

export default function DashboardMessages() {
  const { user } = useUser();
  return (
    <div>
      <h2>Messages</h2>
      <p>Hello, {user.name}!</p>
    </div>
  );
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-outlet-context>

`useLinkPressHandler`
======================


 Type declaration
```
declare function useLinkPressHandler(
  to: To,
  options?: {
    replace?: boolean;
    state?: any;
  }
): (event: GestureResponderEvent) => void;

```
The `react-router-native` counterpart to `useLinkClickHandler`, `useLinkPressHandler` returns a press event handler for custom `<Link>` navigation.



```
import { TouchableHighlight } from "react-native";
import { useLinkPressHandler } from "react-router-native";

function Link({
  onPress,
  replace = false,
  state,
  to,
  ...rest
}) {
  let handlePress = useLinkPressHandler(to, {
    replace,
    state,
  });

  return (
    <TouchableHighlight
      {...rest}
      onPress={(event) => {
        onPress?.(event);
        if (!event.defaultPrevented) {
          handlePress(event);
        }
      }}
    />
  );
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-link-press-handler>

`useNavigationType`
====================


 Type declaration
```
declare function useNavigationType(): NavigationType;

type NavigationType = "POP" | "PUSH" | "REPLACE";

```
This hook returns the current type of navigation or how the user came to the current page; either via a pop, push, or replace action on the history stack.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-navigation-type>

`useResolvedPath`
==================


 Type declaration
```
declare function useResolvedPath(
  to: To,
  options?: { relative?: RelativeRoutingType }
): Path;

```
This hook resolves the `pathname` of the location in the given `to` value against the pathname of the current location.


This is useful when building links from relative values. For example, check out the source to [`<NavLink>`](../components/nav-link) which calls `useResolvedPath` internally to resolve the full pathname of the page being linked to.


See [resolvePath](../utils/resolve-path) for more information.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-resolved-path>

`useParams`
============


 Type declaration
```
declare function useParams<
  K extends string = string
>(): Readonly<Params<K>>;

```
The `useParams` hook returns an object of key/value pairs of the dynamic params from the current URL that were matched by the `<Route path>`. Child routes inherit all params from their parent routes.



```
import * as React from 'react';
import { Routes, Route, useParams } from 'react-router-dom';

function ProfilePage() {
  // Get the userId param from the URL.
  let { userId } = useParams();
  // ...
}

function App() {
  return (
    <Routes>
      <Route path="users">
        <Route path=":userId" element={<ProfilePage />} />
        <Route path="me" element={...} />
      </Route>
    </Routes>
  );
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-params>

`useMatches`
=============


Returns the current route matches on the page. This is most useful for creating abstractions in parent layouts to get access to their child route's data.



```
import { useMatches } from "react-router-dom";

function SomeComponent() {
  const matches = useMatches();
  // [match1, match2, ...]
}

```

A `match` has the following shape:



```
{
  // route id
  id,

  // the portion of the URL the route matched
  pathname,

  // the data from the loader
  data,

  // the parsed params from the URL
  params,

  // the <Route handle> with any app specific data
  handle,
};

```

Pairing `<Route handle>` with `useMatches` gets very powerful since you can put whatever you want on a route `handle` and have access to `useMatches` anywhere.


`useMatches` only works with a data router like [`createBrowserRouter`](../routers/create-browser-router), since they know the full route tree up front and can provide all of the current matches. Additionally, `useMatches` will not match down into any descendant route trees since the router isn't aware of the descendant routes.



Breadcrumbs
------------


The proverbial use case here is adding breadcrumbs to a parent layout that uses data from the child routes.



```
<Route element={<Root />}>
  <Route
    path="messages"
    element={<Messages />}
    loader={loadMessages}
    handle={{
      // you can put whatever you want on a route handle
      // here we use "crumb" and return some elements,
      // this is what we'll render in the breadcrumbs
      // for this route
      crumb: () => <Link to="/message">Messages</Link>,
    }}
  >
    <Route
      path="conversation/:id"
      element={<Thread />}
      loader={loadThread}
      handle={{
        // `crumb` is your own abstraction, we decided
        // to make this one a function so we can pass
        // the data from the loader to it so that our
        // breadcrumb is made up of dynamic content
        crumb: (data) => <span>{data.threadName}</span>,
      }}
    />
  </Route>
</Route>

```

Now we can create a `Breadcrumbs` component that takes advantage of our home-grown `crumb` abstraction with `useMatches` and `handle`.



```
function Breadcrumbs() {
  let matches = useMatches();
  let crumbs = matches
    // first get rid of any matches that don't have handle and crumb
    .filter((match) => Boolean(match.handle?.crumb))
    // now map them into an array of elements, passing the loader
    // data to each one
    .map((match) => match.handle.crumb(match.data));

  return (
    <ol>
      {crumbs.map((crumb, index) => (
        <li key={index}>{crumb}</li>
      ))}
    </ol>
  );
}

```

Now you can render `<Breadcrumbs/>` anywhere you want, probably in the root component.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-matches>

`useRevalidator`
=================


This hook allows you to revalidate the data for any reason. React Router automatically revalidates the data after actions are called, but you may want to revalidate for other reasons like when focus returns to the window.



```
import { useRevalidator } from "react-router-dom";

function WindowFocusRevalidator() {
  let revalidator = useRevalidator();

  useFakeWindowFocus(() => {
    revalidator.revalidate();
  });

  return (
    <div hidden={revalidator.state === "idle"}>
      Revalidating...
    </div>
  );
}

```

Again, React Router already revalidates the data on the page automatically in the vast majority of cases so this should rarely be needed. If you find yourself using this for normal CRUD operations on your data in response to user interactions, you're probably not taking advantage of the other APIs like [`<Form>`](../components/form), [`useSubmit`](use-submit), or [`useFetcher`](use-fetcher) that do this automatically.



`revalidator.state`
--------------------


Tells you the state the revalidation is in, either `"idle"` or `"loading"`.


This is useful for creating loading indicators and spinners to let the user know the app is thinking.



`revalidator.revalidate()`
---------------------------


This initiates a revalidation.



```
function useLivePageData() {
  let revalidator = useRevalidator();
  let interval = useInterval(5000);

  useEffect(() => {
    if (revalidator.state === "idle") {
      revalidator.revalidate();
    }
  }, [interval]);
}

```


Notes
------


While you can render multiple occurrences of `useRevalidator` at the same time, underneath it is a singleton. This means when one `revalidator.revalidate()` is called, all instances go into the `"loading"` state together (or rather, they all update to report the singleton state).


Race conditions are automatically handled when calling `revalidate()` when a revalidation is already in progress.


If a navigation happens while a revalidation is in flight, the revalidation will be cancelled and fresh data will be requested from all loaders for the next page.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-revalidator>

`useRouteError`
================


Inside of an [`errorElement`](../route/error-element), this hooks returns anything thrown during an action, loader, or rendering. Note that thrown responses have special treatment, see [`isRouteErrorResponse`](../utils/is-route-error-response) for more information.



```
function ErrorBoundary() {
  const error = useRouteError();
  console.error(error);
  return <div>{error.message}</div>;
}

<Route
  errorElement={<ErrorBoundary />}
  loader={() => {
    // unexpected errors in loaders/actions
    something.that.breaks();
  }}
  action={() => {
    // stuff you throw on purpose in loaders/actions
    throw new Response("Bad Request", { status: 400 });
  }}
  element={
    // and errors thrown while rendering
    <div>{breaks.while.rendering}</div>
  }
/>;

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-route-error>

`createRoutesFromChildren`
===========================


Alias for [`createRoutesFromElements`](create-routes-from-elements)



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/create-routes-from-children>

`useRoutes`
============


 Type declaration
```
declare function useRoutes(
  routes: RouteObject[],
  location?: Partial<Location> | string;
): React.ReactElement | null;

```
The `useRoutes` hook is the functional equivalent of [`<Routes>`](../components/routes), but it uses JavaScript objects instead of `<Route>` elements to define your routes. These objects have the same properties as normal [`<Route>` elements](../components/route), but they don't require JSX.


The return value of `useRoutes` is either a valid React element you can use to render the route tree, or `null` if nothing matched.



```
import * as React from "react";
import { useRoutes } from "react-router-dom";

function App() {
  let element = useRoutes([
    {
      path: "/",
      element: <Dashboard />,
      children: [
        {
          path: "messages",
          element: <DashboardMessages />,
        },
        { path: "tasks", element: <DashboardTasks /> },
      ],
    },
    { path: "team", element: <AboutPage /> },
  ]);

  return element;
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-routes>

`useSearchParams`
==================


This is the web version of `useSearchParams`. For the React Native version, [go here](use-search-params-rn).


 Type declaration
```
declare function useSearchParams(
  defaultInit?: URLSearchParamsInit
): [URLSearchParams, SetURLSearchParams];

type ParamKeyValuePair = [string, string];

type URLSearchParamsInit =
  | string
  | ParamKeyValuePair[]
  | Record<string, string | string[]>
  | URLSearchParams;

type SetURLSearchParams = (
  nextInit?:
    | URLSearchParamsInit
    | ((prev: URLSearchParams) => URLSearchParamsInit),
  navigateOpts?: : NavigateOptions
) => void;

interface NavigateOptions {
  replace?: boolean;
  state?: any;
  preventScrollReset?: boolean;
}

```
The `useSearchParams` hook is used to read and modify the query string in the URL for the current location. Like React's own [`useState` hook](https://reactjs.org/docs/hooks-reference.html#usestate), `useSearchParams` returns an array of two values: the current location's [search params](https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams) and a function that may be used to update them. Just as React's [`useState` hook](https://reactjs.org/docs/hooks-reference.html#usestate), `setSearchParams` also supports [functional updates](https://reactjs.org/docs/hooks-reference.html#functional-updates). Therefore, you may provide a function that takes a `searchParams` and returns an updated version.



```
import * as React from "react";
import { useSearchParams } from "react-router-dom";

function App() {
  let [searchParams, setSearchParams] = useSearchParams();

  function handleSubmit(event) {
    event.preventDefault();
    // The serialize function here would be responsible for
    // creating an object of { key: value } pairs from the
    // fields in the form that make up the query.
    let params = serializeFormQuery(event.target);
    setSearchParams(params);
  }

  return (
    <div>
      <form onSubmit={handleSubmit}>{/* ... */}</form>
    </div>
  );
}

```

The `setSearchParams` function works like [`navigate`](use-navigate), but only for the [search portion](https://developer.mozilla.org/en-US/docs/Web/API/Location/search) of the URL. Also note that the second arg to `setSearchParams` is the same type as the second arg to `navigate`.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-search-params>

`useSearchParams` (React Native)
=================================


This is the React Native version of `useSearchParams`. For the web version, [go here](use-search-params.md).


 Type declaration
```
declare function useSearchParams(
  defaultInit?: URLSearchParamsInit
): [URLSearchParams, SetURLSearchParams];

type ParamKeyValuePair = [string, string];

type URLSearchParamsInit =
  | string
  | ParamKeyValuePair[]
  | Record<string, string | string[]>
  | URLSearchParams;

type SetURLSearchParams = (
  nextInit?:
    | URLSearchParamsInit
    | ((prev: URLSearchParams) => URLSearchParamsInit),
  navigateOpts?: : NavigateOptions
) => void;

interface NavigateOptions {
  replace?: boolean;
  state?: any;
  preventScrollReset?: boolean;
}

```
The `useSearchParams` hook is used to read and modify the query string in the URL for the current location. Like React's own [`useState` hook](https://reactjs.org/docs/hooks-reference.html#usestate), `useSearchParams` returns an array of two values: the current location's [search params](https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams) and a function that may be used to update them. Just as React's [`useState` hook](https://reactjs.org/docs/hooks-reference.html#usestate), `setSearchParams` also supports [functional updates](https://reactjs.org/docs/hooks-reference.html#functional-updates). Therefore, you may provide a function that takes a `searchParams` and returns an updated version.



```
import * as React from "react";
import { View, SearchForm, TextInput } from "react-native";
import { useSearchParams } from "react-router-native";

function App() {
  let [searchParams, setSearchParams] = useSearchParams();
  let [query, setQuery] = React.useState(
    searchParams.get("query")
  );

  function handleSubmit() {
    setSearchParams({ query });
  }

  return (
    <View>
      <SearchForm onSubmit={handleSubmit}>
        <TextInput value={query} onChangeText={setQuery} />
      </SearchForm>
    </View>
  );
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-search-params-rn>

`defer`
========


This utility allows you to defer values returned from loaders by passing promises instead of resolved values.



```
function loader() {
  let product = await getProduct();
  let reviews = getProductReviews();
  return defer({ product, reviews });
}

```

See the [Deferred Guide](../guides/deferred) for more information.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/defer>

`useSubmit`
============


The imperative version of `<Form>` that let's you, the programmer, submit a form instead of the user. For example, submitting the form every time a value changes inside the form:



```
import { useSubmit, Form } from "react-router-dom";

function SearchField() {
  let submit = useSubmit();
  return (
    <Form
      onChange={(event) => {
        submit(event.currentTarget);
      }}
    >
      <input type="text" name="search" />
      <button type="submit">Search</button>
    </Form>
  );
}

```

This can also be useful if you'd like to automatically sign someone out of your website after a period of inactivity. In this case, we've defined inactivity as the user hasn't navigated to any other pages after 5 minutes.



```
import { useSubmit, useLocation } from "react-router-dom";
import { useEffect } from "react";

function AdminPage() {
  useSessionTimeout();
  return <div>{/* ... */}</div>;
}

function useSessionTimeout() {
  const submit = useSubmit();
  const location = useLocation();

  useEffect(() => {
    const timer = setTimeout(() => {
      submit(null, { method: "post", action: "/logout" });
    }, 5 * 60_000);

    return () => clearTimeout(timer);
  }, [submit, location]);
}

```


Submit target
--------------


The first argument to submit accepts many different values.


You can submit any form or form input element:



```
// input element events
<input onChange={(event) => submit(event.currentTarget)} />;

// React refs
let ref = useRef();
<button ref={ref} />;
submit(ref.current);

```

You can submit `FormData`:



```
let formData = new FormData();
formData.append("cheese", "gouda");
submit(formData);

```


Submit options
---------------


The second argument is a set of options that map directly to form submission attributes:



```
submit(null, {
  action: "/logout",
  method: "post",
});

// same as
<Form action="/logout" method="post" />;

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-submit>

Tutorial
=========


Welcome to the tutorial! We'll be building a small, but feature-rich app that let's you keep track of your contacts. We expect it to take between 30-60m if you're following along.


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/15.webp)👉 **Every time you see this it means you need to do something in the app!**


The rest is just there for your information and deeper understanding. Let's get to it.



Setup
------


If you're not going to follow along in your own app, you can skip this section


We'll be using [Vite](https://vitejs.dev/guide/) for our bundler and dev server for this tutorial. You'll need [Node.js](https://nodejs.org) installed for the `npm` command line tool.


👉️ **Open up your terminal and bootstrap a new React app with Vite:**



```
npm create vite@latest name-of-your-project -- --template react
# follow prompts
cd <your new project directory>
npm install react-router-dom localforage match-sorter sort-by
npm run dev

```

You should be able to visit the URL printed in the terminal:


We've got some pre-written CSS for this tutorial so we can stay focused on React Router. Feel free to judge it harshly or write your own 😅 (We did things we normally wouldn't in CSS so that the markup in this tutorial could stay as minimal as possible.)


👉 **Copy/Paste the tutorial CSS [found here](https://gist.githubusercontent.com/ryanflorence/ba20d473ef59e1965543fa013ae4163f/raw/499707f25a5690d490c7b3d54c65c65eb895930c/react-router-6.4-tutorial-css.css) into `src/index.css`**


This tutorial will be creating, reading, searching, updating, and deleting data. A typical web app would probably be talking to an API on your web server, but we're going to use browser storage and fake some network latency to keep this focused. None of this code is relevant to React Router, so just go ahead and copy/paste it all.


👉 **Copy/Paste the tutorial data module [found here](https://gist.githubusercontent.com/ryanflorence/1e7f5d3344c0db4a8394292c157cd305/raw/f7ff21e9ae7ffd55bfaaaf320e09c6a08a8a6611/contacts.js) into `src/contacts.js`**


All you need in the src folder are `contacts.js`, `main.jsx`, and `index.css`. You can delete anything else (like `App.js` and `assets`, etc.).


👉 **Delete unused files in `src/` so all you have left are these:**


If your app is running, it might blow up momentarily, just keep going 😋. And with that, we're ready to get started!



Adding a Router
----------------


First thing to do is create a [Browser Router](../routers/create-browser-router) and configure our first route. This will enable client side routing for our web app.


The `main.jsx` file is the entry point. Open it up and we'll put React Router on the page.


👉 **Create and render a [browser router](../routers/create-browser-router) in `main.jsx`**



```
import React from "react";
import ReactDOM from "react-dom/client";
import {
  createBrowserRouter,
  RouterProvider,
  Route,
} from "react-router-dom";
import "./index.css";

const router = createBrowserRouter([
  {
    path: "/",
    element: <div>Hello world!</div>,
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

```

This first route is what we often call the "root route" since the rest of our routes will render inside of it. It will serve as the root layout of the UI, we'll have nested layouts as we get farther along.



The Root Route
---------------


Let's add the global layout for this app.


👉 **Create `src/routes` and `src/routes/root.jsx`**



```
mkdir src/routes
touch src/routes/root.jsx

```

(If you don't want to be a command line nerd, use your editor instead of those commands 🤓)


👉 **Create the root layout component**



```
export default function Root() {
  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        <div>
          <form id="search-form" role="search">
            <input
              id="q"
              aria-label="Search contacts"
              placeholder="Search"
              type="search"
              name="q"
            />
            <div
              id="search-spinner"
              aria-hidden
              hidden={true}
            />
            <div
              className="sr-only"
              aria-live="polite"
            ></div>
          </form>
          <form method="post">
            <button type="submit">New</button>
          </form>
        </div>
        <nav>
          <ul>
            <li>
              <a href={`contacts/1`}>Your Name</a>
            </li>
            <li>
              <a href={`contacts/2`}>Your Friend</a>
            </li>
          </ul>
        </nav>
      </div>
      <div id="detail"></div>
    </>
  );
}

```

Nothing React Router specific yet, so feel free to copy/paste all of that.


👉 **Set `<Root>` as the root route's [`element`](../route/route#element)**



```
/* existing imports */
import Root from "./routes/root";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

```

The app should look something like this now. It sure is nice having a designer who can also write the CSS, isn't it? (Thank you [Jim](https://blog.jim-nielsen.com/) 🙏).


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/01.webp)
Handling Not Found Errors
--------------------------


It's always a good idea to know how your app responds to errors early in the project because we all write far more bugs than features when building a new app! Not only will your users get a good experience when this happens, but it helps you during development as well.


We added some links to this app, let's see what happens when we click them?


👉 **Click one of the sidebar names**


![screenshot of default React Router error element](https://reactrouterdotcom.fly.dev/_docs/tutorial/02.webp)Gross! This is the default error screen in React Router, made worse by our flex box styles on the root element in this app 😂.


Anytime your app throws an error while rendering, loading data, or performing data mutations, React Router will catch it and render an error screen. Let's make our own error page.


👉 **Create an error page component**



```
touch src/error-page.jsx

```


```
import { useRouteError } from "react-router-dom";

export default function ErrorPage() {
  const error = useRouteError();
  console.error(error);

  return (
    <div id="error-page">
      <h1>Oops!</h1>
      <p>Sorry, an unexpected error has occurred.</p>
      <p>
        <i>{error.statusText || error.message}</i>
      </p>
    </div>
  );
}

```

👉 **Set the `<ErrorPage>` as the [`errorElement`](../route/error-element) on the root route**



```
/* previous imports */
import ErrorPage from "./error-page";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

```

The error page should now look like this:


![new error page, but still ugly](https://reactrouterdotcom.fly.dev/_docs/tutorial/03.webp)(Well, that's not much better. Maybe somebody forgot to ask the designer to make an error page. Maybe everybody forgets to ask the designer to make an error page and then blames the designer for not thinking of it 😆)


Note that [`useRouteError`](../hooks/use-route-error) provides the error that was thrown. When the user navigates to routes that don't exist you'll get an [error response](../utils/is-route-error-response) with a "Not Found" `statusText`. We'll see some other errors later in the tutorial and discuss them more.


For now, it's enough to know that pretty much all of your errors will now be handled by this page instead of infinite spinners, unresponsive pages, or blank screens 🙌



The Contact Route UI
---------------------


Instead of a 404 "Not Found" page, we want to actually render something at the URLs we've linked to. For that, we need to make a new route.


👉 **Create the contact route module**



```
touch src/routes/contact.jsx

```

👉 **Add the contact component UI**


It's just a bunch of elements, feel free to copy/paste.



```
import { Form } from "react-router-dom";

export default function Contact() {
  const contact = {
    first: "Your",
    last: "Name",
    avatar: "https://placekitten.com/g/200/200",
    twitter: "your_handle",
    notes: "Some notes",
    favorite: true,
  };

  return (
    <div id="contact">
      <div>
        <img
          key={contact.avatar}
          src={contact.avatar || null}
        />
      </div>

      <div>
        <h1>
          {contact.first || contact.last ? (
            <>
              {contact.first} {contact.last}
            </>
          ) : (
            <i>No Name</i>
          )}{" "}
          <Favorite contact={contact} />
        </h1>

        {contact.twitter && (
          <p>
            <a
              target="_blank"
              href={`https://twitter.com/${contact.twitter}`}
            >
              {contact.twitter}
            </a>
          </p>
        )}

        {contact.notes && <p>{contact.notes}</p>}

        <div>
          <Form action="edit">
            <button type="submit">Edit</button>
          </Form>
          <Form
            method="post"
            action="destroy"
            onSubmit={(event) => {
              if (
                !confirm(
                  "Please confirm you want to delete this record."
                )
              ) {
                event.preventDefault();
              }
            }}
          >
            <button type="submit">Delete</button>
          </Form>
        </div>
      </div>
    </div>
  );
}

function Favorite({ contact }) {
  // yes, this is a `let` for later
  let favorite = contact.favorite;
  return (
    <Form method="post">
      <button
        name="favorite"
        value={favorite ? "false" : "true"}
        aria-label={
          favorite
            ? "Remove from favorites"
            : "Add to favorites"
        }
      >
        {favorite ? "★" : "☆"}
      </button>
    </Form>
  );
}

```

Now that we've got a component, let's hook it up to a new route.


👉 **Import the contact component and create a new route**



```
/* existing imports */
import Contact from "./routes/contact";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
  },
  {
    path: "contacts/:contactId",
    element: <Contact />,
  },
]);

/* existing code */

```

Now if we click one of the links or visit `/contacts/1` we get our new component!


![contact route rendering without the parent layout](https://reactrouterdotcom.fly.dev/_docs/tutorial/04.webp)However, it's not inside of our root layout 😠



Nested Routes
--------------


We want the contact component to render *inside* of the `<Root>` layout like this.


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/05.webp)We do it by making the contact route a *child* of the root route.


👉 **Move the contacts route to be a child of the root route**



```
const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
      },
    ],
  },
]);

```

You'll now see the root layout again but a blank page on the right. We need to tell the root route *where* we want it to render its child routes. We do that with [`<Outlet>`](../components/outlet).


Find the `<div id="detail">` and put an outlet inside


👉 **Render an [`<Outlet>`](../components/outlet)**



```
import { Outlet } from "react-router-dom";

export default function Root() {
  return (
    <>
      {/* all the other elements */}
      <div id="detail">
        <Outlet />
      </div>
    </>
  );
}

```


Client Side Routing
--------------------


You may or may not have noticed, but when we click the links in the sidebar, the browser is doing a full document request for the next URL instead of using React Router.


Client side routing allows our app to update the URL without requesting another document from the server. Instead, the app can immediately render new UI. Let's make it happen with [`<Link>`](../components/link).


👉 **Change the sidebar `<a href>` to `<Link to>`**



```
import { Outlet, Link } from "react-router-dom";

export default function Root() {
  return (
    <>
      <div id="sidebar">
        {/* other elements */}

        <nav>
          <ul>
            <li>
              <Link to={`contacts/1`}>Your Name</Link>
            </li>
            <li>
              <Link to={`contacts/2`}>Your Friend</Link>
            </li>
          </ul>
        </nav>

        {/* other elements */}
      </div>
    </>
  );
}

```

You can open the network tab in the browser devtools to see that it's not requesting documents anymore.



Loading Data
-------------


URL segments, layouts, and data are more often than not coupled (tripled?) together. We can see it in this app already:




| URL Segment | Component | Data |
| --- | --- | --- |
| / | `<Root>` | list of contacts |
| contacts/:id | `<Contact>` | individual contact |


Because of this natural coupling, React Router has data conventions to get data into your route components easily.


There are two APIs we'll be using to load data, [`loader`](../route/loader) and [`useLoaderData`](../hooks/use-loader-data). First we'll create and export a loader function in the root module, then we'll hook it up to the route. Finally, we'll access and render the data.


👉 **Export a loader from `root.jsx`**



```
import { Outlet, Link } from "react-router-dom";
import { getContacts } from "../contacts";

export async function loader() {
  const contacts = await getContacts();
  return { contacts };
}

```

👉 **Configure the loader on the route**



```
/* other imports */
import Root, { loader as rootLoader } from "./routes/root";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
      },
    ],
  },
]);

```

👉 **Access and render the data**



```
import {
  Outlet,
  Link,
  useLoaderData,
} from "react-router-dom";
import { getContacts } from "../contacts";

/* other code */

export default function Root() {
  const { contacts } = useLoaderData();
  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        {/* other code */}

        <nav>
          {contacts.length ? (
            <ul>
              {contacts.map((contact) => (
                <li key={contact.id}>
                  <Link to={`contacts/${contact.id}`}>
                    {contact.first || contact.last ? (
                      <>
                        {contact.first} {contact.last}
                      </>
                    ) : (
                      <i>No Name</i>
                    )}{" "}
                    {contact.favorite && <span>★</span>}
                  </Link>
                </li>
              ))}
            </ul>
          ) : (
            <p>
              <i>No contacts</i>
            </p>
          )}
        </nav>

        {/* other code */}
      </div>
    </>
  );
}

```

That's it! React Router will now automatically keep that data in sync with your UI. We don't have any data yet, so you're probably getting a blank list like this:


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/06.webp)
Data Writes + HTML Forms
-------------------------


We'll create our first contact in a second, but first let's talk about HTML.


React Router emulates HTML Form navigation as the data mutation primitive, a la web development before the JavaScript cambrian explosion. It gives you the UX capabilities of client rendered apps with the simplicity of the "old school" web model.


While unfamiliar to some web developers, HTML forms actually cause a navigation in the browser, just like clicking a link. The only difference is in the request: links can only change the URL while forms can also change the request method (GET vs POST) and the request body (POST form data).


Without client side routing, the browser will serialize the form's data automatically and send it to the server as the request body for POST, and as URLSearchParams for GET. React Router does the same thing, except instead of sending the request to the server, it uses client side routing and sends it to a route [`action`](../route/action).


We can test this out by clicking the "New" button in our app. The app should blow up because the Vite server isn't configured to handle a POST request (it sends a 404, though it should probably be a 405 🤷).


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/07.webp)Instead of sending that POST to the Vite server to create a new contact, let's use client side routing instead.



Creating Contacts
------------------


We'll create new contacts by exporting an `action` in our root route, wiring it up to the route config, and changing our `<form>` to a React Router [`<Form>`](../components/form).


👉 **Create the action and change `<form>` to `<Form>`**



```
import {
  Outlet,
  Link,
  useLoaderData,
  Form,
} from "react-router-dom";
import { getContacts, createContact } from "../contacts";

export async function action() {
  await createContact();
}

/* other code */

export default function Root() {
  const { contacts } = useLoaderData();
  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        <div>
          {/* other code */}
          <Form method="post">
            <button type="submit">New</button>
          </Form>
        </div>

        {/* other code */}
      </div>
    </>
  );
}

```

👉 **Import and set the action on the route**



```
/* other imports */

import Root, {
  loader as rootLoader,
  action as rootAction,
} from "./routes/root";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    action: rootAction,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
      },
    ],
  },
]);

```

That's it! Go ahead and click the "New" button and you should see a new record pop into the list 🥳


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/08.webp)The `createContact` method just creates an empty contact with no name or data or anything. But it does still create a record, promise!



>  🧐 Wait a sec ... How did the sidebar update? Where did we call the `action`? Where's the code to refetch the data? Where are `useState`, `onSubmit` and `useEffect`?!
> 
>  


This is where the "old school web" programming model shows up. As we discussed earlier, [`<Form>`](../components/form) prevents the browser from sending the request to the server and sends it to your route `action` instead. In web semantics, a POST usually means some data is changing. By convention, React Router uses this as a hint to automatically revalidate the data on the page after the action finishes. That means all of your `useLoaderData` hooks update and the UI stays in sync with your data automatically! Pretty cool.



URL Params in Loaders
----------------------


👉 **Click on the No Name record**


We should be seeing our old static contact page again, with one difference: the URL now has a real ID for the record.


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/09.webp)Reviewing the route config, the route looks like this:



```
[
  {
    path: "contacts/:contactId",
    element: <Contact />,
  },
];

```

Note the `:contactId` URL segment. The colon (`:`) has special meaning, turning it into a "dynamic segment". Dynamic segments will match dynamic (changing) values in that position of the URL, like the contact ID. We call these values in the URL "URL Params", or just "params" for short.


These [`params`](../route/loader#params) are passed to the loader with keys that match the dynamic segment. For example, our segment is named `:contactId` so the value will be passed as `params.contactId`.


These params are most often used to find a record by ID. Let's try it out.


👉 **Add a loader to the contact page and access data with `useLoaderData`**



```
import { Form, useLoaderData } from "react-router-dom";
import { getContact } from "../contacts";

export async function loader({ params }) {
  return getContact(params.contactId);
}

export default function Contact() {
  const contact = useLoaderData();
  // existing code
}

```

👉 **Configure the loader on the route**



```
/* existing code */
import Contact, {
  loader as contactLoader,
} from "./routes/contact";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    action: rootAction,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
        loader: contactLoader,
      },
    ],
  },
]);

/* existing code */

```

![](https://reactrouterdotcom.fly.dev/_docs/tutorial/10.webp)
Updating Data
--------------


Just like creating data, you update data with [`<Form>`](../components/form). Let's make a new route at `contacts/:contactId/edit`. Again, we'll start with the component and then wire it up to the route config.


👉 **Create the edit component**


👉 **Add the edit page UI**


Nothing we haven't seen before, feel free to copy/paste:



```
import { Form, useLoaderData } from "react-router-dom";
import { getContact } from "../contacts";

export function loader({ params }) {
  return getContact(params.contactId);
}

export default function EditContact() {
  const contact = useLoaderData();

  return (
    <Form method="post" id="contact-form">
      <p>
        <span>Name</span>
        <input
          placeholder="First"
          aria-label="First name"
          type="text"
          name="first"
          defaultValue={contact.first}
        />
        <input
          placeholder="Last"
          aria-label="Last name"
          type="text"
          name="last"
          defaultValue={contact.last}
        />
      </p>
      <label>
        <span>Twitter</span>
        <input
          type="text"
          name="twitter"
          placeholder="@jack"
          defaultValue={contact.twitter}
        />
      </label>
      <label>
        <span>Avatar URL</span>
        <input
          placeholder="https://example.com/avatar.jpg"
          aria-label="Avatar URL"
          type="text"
          name="avatar"
          defaultValue={contact.avatar}
        />
      </label>
      <label>
        <span>Notes</span>
        <textarea
          name="notes"
          defaultValue={contact.notes}
          rows={6}
        />
      </label>
      <p>
        <button type="submit">Save</button>
        <button type="button">Cancel</button>
      </p>
    </Form>
  );
}

```

👉 **Add the new edit route**



```
/* existing code */
import EditContact from "./routes/edit";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    action: rootAction,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
        loader: contactLoader,
      },
      {
        path: "contacts/:contactId/edit",
        element: <EditContact />,
        loader: contactLoader,
      },
    ],
  },
]);

/* existing code */

```

We want it to be rendered in the root route's outlet, so we made it a sibling to the existing child route.


(You might note we reused the `contactLoader` for this route. This is only because we're being lazy in the tutorial. There is no reason to attempt to share loaders among routes, they usually have their own.)


Alright, clicking the "Edit" button gives us this new UI:


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/11.webp)
Updating Contacts with FormData
--------------------------------


The edit route we just created already renders a form. All we need to do to update the record is wire up an action to the route. The form will post to the action and the data will be automatically revalidated.


👉 **Add an action to the edit module**



```
import {
  Form,
  useLoaderData,
  redirect,
} from "react-router-dom";
import { getContact, updateContact } from "../contacts";

export async function action({ request, params }) {
  const formData = await request.formData();
  const updates = Object.fromEntries(formData);
  await updateContact(params.contactId, updates);
  return redirect(`/contacts/${params.contactId}`);
}

/* existing code */

```

👉 **Wire the action up to the route**



```
/* existing code */
import EditContact, {
  action as editAction,
} from "./routes/edit";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    action: rootAction,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
        loader: contactLoader,
      },
      {
        path: "contacts/:contactId/edit",
        element: <EditContact />,
        loader: contactLoader,
        action: editAction,
      },
    ],
  },
]);

/* existing code */

```

Fill out the form, hit save, and you should see something like this! (Except easier on the eyes and maybe less hairy.)


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/12.webp)
Mutation Discussion
--------------------



>  😑 It worked, but I have no idea what is going on here...
> 
>  


Let's dig in a bit...


Open up `src/routes/edit.jsx` and look at the form elements. Notice how they each have a name:



```
<input
  placeholder="First"
  aria-label="First name"
  type="text"
  name="first"
  defaultValue={contact.first}
/>

```

Without JavaScript, when a form is submitted, the browser will create [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) and set it as the body of the request when it sends it to the server. As mentioned before, React Router prevents that and sends the request to your action instead, including the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).


Each field in the form is accessible with `formData.get(name)`. For example, given the input field from above, you could access the first and last names like this:



```
export async function action({ request, params }) {
  const formData = await request.formData();
  const firstName = formData.get("first");
  const lastName = formData.get("last");
  // ...
}

```

Since we have a handful of form fields, we used [`Object.fromEntries`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) to collect them all into an object, which is exactly what our `updateContact` function wants.



```
const updates = Object.fromEntries(formData);
updates.first; // "Some"
updates.last; // "Name"

```

Aside from `action`, none of these APIs we're discussing are provided by React Router: [`request`](https://developer.mozilla.org/en-US/docs/Web/API/Request), [`request.formData`](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData), [`Object.fromEntries`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) are all provided by the web platform.


After we finished the action, note the [`redirect`](../fetch/redirect) at the end:



```
export async function action({ request, params }) {
  const formData = await request.formData();
  const updates = Object.fromEntries(formData);
  await updateContact(params.contactId, updates);
  return redirect(`/contacts/${params.contactId}`);
}

```

Loaders and actions can both [return a `Response`](../route/loader#returning-responses) (makes sense, since they received a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)!). The [`redirect`](../fetch/redirect) helper just makes it easier to return a [response](https://developer.mozilla.org/en-US/docs/Web/API/Response) that tells the app to change locations.


Without client side routing, if a server redirected after a POST request, the new page would fetch the latest data and render. As we learned before, React Router emulates this model and automatically revalidates the data on the page after the action. That's why the sidebar automatically updates when we save the form. The extra revalidation code doesn't exist without client side routing, so it doesn't need to exist with client side routing either!



Redirecting new records to the edit page
-----------------------------------------


Now that we know how to redirect, let's update the action that creates new contacts to redirect to the edit page:


👉 **Redirect to the new record's edit page**



```
import {
  Outlet,
  Link,
  useLoaderData,
  Form,
  redirect,
} from "react-router-dom";
import { getContacts, createContact } from "../contacts";

export async function action() {
  const contact = await createContact();
  return redirect(`/contacts/${contact.id}/edit`);
}

```

Now when we click "New", we should end up on the edit page:


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/13.webp)👉 **Add a handful of records**


I'm going to use the stellar lineup of speakers from the first Remix Conference 😁


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/14.webp)
Active Link Styling
--------------------


Now that we have a bunch of records, it's not clear which one we're looking at in the sidebar. We can use [`NavLink`](../components/nav-link) to fix this.


👉 **Use a `NavLink` in the sidebar**



```
import {
  Outlet,
  NavLink,
  useLoaderData,
  Form,
  redirect,
} from "react-router-dom";

export default function Root() {
  return (
    <>
      <div id="sidebar">
        {/* other code */}

        <nav>
          {contacts.length ? (
            <ul>
              {contacts.map((contact) => (
                <li key={contact.id}>
                  <NavLink
                    to={`contacts/${contact.id}`}
                    className={({ isActive, isPending }) =>
                      isActive
                        ? "active"
                        : isPending
                        ? "pending"
                        : ""
                    }
                  >
                    {/* other code */}
                  </NavLink>
                </li>
              ))}
            </ul>
          ) : (
            <p>{/* other code */}</p>
          )}
        </nav>
      </div>
    </>
  );
}

```

Note that we are passing a function to `className`. When the user is at the URL in the `NavLink`, then `isActive` will be true. When it's *about* to be active (the data is still loading) then `isPending` will be true. This allows us to easily indicate where the user is, as well as provide immediate feedback on links that have been clicked but we're still waiting for data to load.


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/15.webp)
Global Pending UI
------------------


As the user navigates the app, React Router will *leave the old page up* as data is loading for the next page. You may have noticed the app feels a little unresponsive as you click between the list. Let's provide the user with some feedback so the app doesn't feel unresponsive.


React Router is managing all of the state behind the scenes and reveals the pieces of it you need to build dynamic web apps. In this case, we'll use the [`useNavigation`](../hooks/use-navigation) hook.


👉 **`useNavigation` to add global pending UI**



```
import {
  // existing code
  useNavigation,
} from "react-router-dom";

// existing code

export default function Root() {
  const { contacts } = useLoaderData();
  const navigation = useNavigation();

  return (
    <>
      <div id="sidebar">{/* existing code */}</div>
      <div
        id="detail"
        className={
          navigation.state === "loading" ? "loading" : ""
        }
      >
        <Outlet />
      </div>
    </>
  );
}

```

[`useNavigation`](../hooks/use-navigation) returns the current navigation state: it can be one of `"idle" | "submitting" | "loading"`.


In our case, we add a `"loading"` class to the main part of the app if we're not idle. The CSS then adds a nice fade after a short delay (to avoid flickering the UI for fast loads). You could do anything you want though, like show a spinner or loading bar across the top.


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/16.webp)Note that our data model (`src/contact.js`) has a clientside cache, so navigating to the same contact is fast the second time. This behavior is *not* React Router, it will re-load data for changing routes no matter if you've been there before or not. It does, however, avoid calling the loaders for *unchanging* routes (like the list) during a navigation.



Deleting Records
-----------------


If we review code in the contact route, we can find the delete button looks like this:



```
<Form
  method="post"
  action="destroy"
  onSubmit={(event) => {
    if (
      !confirm(
        "Please confirm you want to delete this record."
      )
    ) {
      event.preventDefault();
    }
  }}
>
  <button type="submit">Delete</button>
</Form>

```

Note the `action` points to `"destroy"`. Like `<Link to>`, `<Form action>` can take a *relative* value. Since the form is rendered in `contact/:contactId`, then a relative action with `destroy` will submit the form to `contact/:contactId/destroy` when clicked.


At this point you should know everything you need to know to make the delete button work. Maybe give it a shot before moving on? You'll need:


1. A new route
2. An `action` at that route
3. `deleteContact` from `src/contacts.js`


👉 **Create the "destroy" route module**


👉 **Add the destroy action**



```
import { redirect } from "react-router-dom";
import { deleteContact } from "../contacts";

export async function action({ params }) {
  await deleteContact(params.contactId);
  return redirect("/");
}

```

👉 **Add the destroy route to the route config**



```
/* existing code */
import { action as destroyAction } from "./routes/destroy";

const router = createBrowserRouter([
  {
    path: "/",
    /* existing root route props */
    children: [
      /* existing routes */
      {
        path: "contacts/:contactId/destroy",
        action: destroyAction,
      },
    ],
  },
]);

/* existing code */

```

Alright, navigate to a record and click the "Delete" button. It works!



>  😅 I'm still confused why this all works
> 
>  


When the user clicks the submit button:


1. `<Form>` prevents the default browser behavior of sending a new POST request to the server, but instead emulates the browser by creating a POST request with client side routing
2. The `<Form action="destroy">` matches the new route at `"contacts/:contactId/destroy"` and sends it the request
3. After the action redirects, React Router calls all of the loaders for the data on the page to get the latest values (this is "revalidation"). `useLoaderData` returns new values and causes the components to update!


Add a form, add an action, React Router does the rest.



Contextual Errors
------------------


Just for kicks, throw an error in the destroy action:



```
export async function action({ params }) {
  throw new Error("oh dang!");
  await deleteContact(params.contactId);
  return redirect("/");
}

```

![](https://reactrouterdotcom.fly.dev/_docs/tutorial/17.webp)Recognize that screen? It's our [`errorElement`](../route/error-element) from before. The user, however, can't really do anything to recover from this screen except to hit refresh.


Let's create a contextual error message for the destroy route:



```
[
  /* other routes */
  {
    path: "contacts/:contactId/destroy",
    action: destroyAction,
    errorElement: <div>Oops! There was an error.</div>,
  },
];

```

Now try it again:


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/18.webp)Our user now has more options than slamming refresh, they can continue to interact with the parts of the page that aren't having trouble 🙌


Because the destroy route has its own `errorElement` and is a child of the root route, the error will render there instead of the root. As you probably noticed, these errors bubble up to the nearest `errorElement`. Add as many or as few as you like, as long as you've got one at the root.



Index Routes
-------------


When we load up the app, you'll notice a big blank page on the right side of our list.


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/19.webp)When a route has children, and you're at the parent route's path, the `<Outlet>` has nothing to render because no children match. You can think of index routes as the default child route to fill in that space.


👉 **Create the index route module**


👉 **Fill in the index component's elements**


Feel free to copy paste, nothing special here.



```
export default function Index() {
  return (
    <p id="zero-state">
      This is a demo for React Router.
      <br />
      Check out{" "}
      <a href="https://reactrouter.com/">
        the docs at reactrouter.com
      </a>
      .
    </p>
  );
}

```

👉 **Configure the index route**



```
// existing code
import Index from "./routes/index";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    action: rootAction,
    children: [
      { index: true, element: <Index /> },
      /* existing routes */
    ],
  },
]);

```

Note the [`{ index:true }`](../route/route#index) instead of [`{ path: "" }`](../route/route#path). That tells the router to match and render this route when the user is at the parent route's exact path, so there are no other child routes to render in the `<Outlet>`.


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/20.webp)Voila! No more blank space. It's common to put dashboards, stats, feeds, etc. at index routes. They can participate in data loading as well.



Cancel Button
--------------


On the edit page we've got a cancel button that doesn't do anything yet. We'd like it to do the same thing as the browser's back button.


We'll need a click handler on the button as well as [`useNavigate`](../hooks/use-navigate) from React Router.


👉 **Add the cancel button click handler with `useNavigate`**



```
import {
  Form,
  useLoaderData,
  redirect,
  useNavigate,
} from "react-router-dom";

export default function Edit() {
  const contact = useLoaderData();
  const navigate = useNavigate();

  return (
    <Form method="post" id="contact-form">
      {/* existing code */}

      <p>
        <button type="submit">Save</button>
        <button
          type="button"
          onClick={() => {
            navigate(-1);
          }}
        >
          Cancel
        </button>
      </p>
    </Form>
  );
}

```

Now when the user clicks "Cancel", they'll be sent back one entry in the browser's history.



>  🧐 Why is there no `event.preventDefault` on the button?
> 
>  


A `<button type="button">`, while seemingly redundant, is the HTML way of preventing a button from submitting its form.


Two more features to go. We're on the home stretch!



URL Search Params and GET Submissions
--------------------------------------


All of our interactive UI so far have been either links that change the URL or forms that post data to actions. The search field is interesting because it's a mix of both: it's a form but it only changes the URL, it doesn't change data.


Right now it's just a normal HTML `<form>`, not a React Router `<Form>`. Let's see what the browser does with it by default:


👉 **Type a name into the search field and hit the enter key**


Note the browser's URL now contains your query in the URL as [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams):


If we review the search form, it looks like this:



```
<form id="search-form" role="search">
  <input
    id="q"
    aria-label="Search contacts"
    placeholder="Search"
    type="search"
    name="q"
  />
  <div id="search-spinner" aria-hidden hidden={true} />
  <div className="sr-only" aria-live="polite"></div>
</form>

```

As we've seen before, browsers can serialize forms by the `name` attribute of it's input elements. The name of this input is `q`, that's why the URL has `?q=`. If we named it `search` the URL would be `?search=`.


Note that this form is different from the others we've used, it does not have `<form method="post">`. The default `method` is `"get"`. That means when the browser creates the request for the next document, it doesn't put the form data into the request POST body, but into the [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) of a GET request.



GET Submissions with Client Side Routing
-----------------------------------------


Let's use client side routing to submit this form and filter the list in our existing loader.


👉 **Change `<form>` to `<Form>`**



```
<Form id="search-form" role="search">
  <input
    id="q"
    aria-label="Search contacts"
    placeholder="Search"
    type="search"
    name="q"
  />
  <div id="search-spinner" aria-hidden hidden={true} />
  <div className="sr-only" aria-live="polite"></div>
</Form>

```

👉 **Filter the list if there are URLSearchParams**



```
export async function loader({ request }) {
  const url = new URL(request.url);
  const q = url.searchParams.get("q");
  const contacts = await getContacts(q);
  return { contacts };
}

```

![](https://reactrouterdotcom.fly.dev/_docs/tutorial/21.webp)Because this is a GET, not a POST, React Router *does not* call the `action`. Submitting a GET form is the same as clicking a link: only the URL changes. That's why the code we added for filtering is in the `loader`, not the `action` of this route.


This also means it's a normal page navigation. You can click the back button to get back to where you were.



Synchronizing URLs to Form State
---------------------------------


There are a couple of UX issues here that we can take care of quickly.


1. If you click back after a search, the form field still has the value you entered even though the list is no longer filtered.
2. If you refresh the page after searching, the form field no longer has the value in it, even though the list is filtered


In other words, the URL and our form state are out of sync.


👉 **Return `q` from your loader and set it as the search field default value**



```
// existing code

export async function loader({ request }) {
  const url = new URL(request.url);
  const q = url.searchParams.get("q");
  const contacts = await getContacts(q);
  return { contacts, q };
}

export default function Root() {
  const { contacts, q } = useLoaderData();
  const navigation = useNavigation();

  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        <div>
          <Form id="search-form" role="search">
            <input
              id="q"
              aria-label="Search contacts"
              placeholder="Search"
              type="search"
              name="q"
              defaultValue={q}
            />
            {/* existing code */}
          </Form>
          {/* existing code */}
        </div>
        {/* existing code */}
      </div>
      {/* existing code */}
    </>
  );
}

```

That solves problem (2). If you refresh the page now, the input field will show the query.


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/21.webp)Now for problem (1), clicking the back button and updating the input. We can bring in `useEffect` from React to manipulate the form's state in the DOM directly.


👉 **Synchronize input value with the URL Search Params**



```
import { useEffect } from "react";

// existing code

export default function Root() {
  const { contacts, q } = useLoaderData();
  const navigation = useNavigation();

  useEffect(() => {
    document.getElementById("q").value = q;
  }, [q]);

  // existing code
}

```


>  🤔 Shouldn't you use a controlled component and React State for this?
> 
>  


You could certainly do this as a controlled component, but you'll end up with more complexity for the same behavior. You don't control the URL, the user does with the back/forward buttons. There would be more synchronization points with a controlled component.


 If you're still concerned, expand this to see what it would look likeNotice how controlling the input requires three points of synchronization now instead of just one. The behavior is identical but the code is more complex.



```
import { useEffect, useState } from "react";
// existing code

export default function Root() {
  const { contacts, q } = useLoaderData();
  const [query, setQuery] = useState(q);
  const navigation = useNavigation();

  useEffect(() => {
    setQuery(q);
  }, [q]);

  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        <div>
          <Form id="search-form" role="search">
            <input
              id="q"
              aria-label="Search contacts"
              placeholder="Search"
              type="search"
              name="q"
              value={query}
              onChange={(e) => {
                setQuery(e.target.value);
              }}
            />
            {/* existing code */}
          </Form>
          {/* existing code */}
        </div>
        {/* existing code */}
      </div>
    </>
  );
}

```

Submitting Forms `onChange`
----------------------------


We've got a product decision to make here. For this UI, we'd probably rather have the filtering happen on every key stroke instead of when the form is explicitly submitted.


We've seen `useNavigate` already, we'll use its cousin, [`useSubmit`](../hooks/use-submit), for this.



```
// existing code
import {
  // existing code
  useSubmit,
} from "react-router-dom";

export default function Root() {
  const { contacts, q } = useLoaderData();
  const navigation = useNavigation();
  const submit = useSubmit();

  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        <div>
          <Form id="search-form" role="search">
            <input
              id="q"
              aria-label="Search contacts"
              placeholder="Search"
              type="search"
              name="q"
              defaultValue={q}
              onChange={(event) => {
                submit(event.currentTarget.form);
              }}
            />
            {/* existing code */}
          </Form>
          {/* existing code */}
        </div>
        {/* existing code */}
      </div>
      {/* existing code */}
    </>
  );
}

```

Now as you type, the form is submitted automatically!


Note the argument to [`submit`](../hooks/use-submit). We're passing in `event.currentTarget.form`. The `currentTarget` is the DOM node the event is attached to, and the `currentTarget.form` is the input's parent form node. The `submit` function will serialize and submit any form you pass to it.



Adding Search Spinner
----------------------


In a production app, it's likely this search will be looking for records in a database that is too large to send all at once and filter client side. That's why this demo has some faked network latency.


Without any loading indicator, the search feels kinda sluggish. Even if we could make our database faster, we'll always have the user's network latency in the way and out of our control. For a better UX, let's add some immediate UI feedback for the search. For this we'll use [`useNavigation`](../hooks/use-navigation) again.


👉 **Add the search spinner**



```
// existing code

export default function Root() {
  const { contacts, q } = useLoaderData();
  const navigation = useNavigation();
  const submit = useSubmit();

  const searching =
    navigation.location &&
    new URLSearchParams(navigation.location.search).has(
      "q"
    );

  useEffect(() => {
    document.getElementById("q").value = q;
  }, [q]);

  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        <div>
          <Form id="search-form" role="search">
            <input
              id="q"
              className={searching ? "loading" : ""}
              // existing code
            />
            <div
              id="search-spinner"
              aria-hidden
              hidden={!searching}
            />
            {/* existing code */}
          </Form>
          {/* existing code */}
        </div>
        {/* existing code */}
      </div>
      {/* existing code */}
    </>
  );
}

```

![](https://reactrouterdotcom.fly.dev/_docs/tutorial/22.webp)The `navigation.location` will show up when the app is navigating to a new URL and loading the data for it. It then goes away when there is no pending navigation anymore.



Managing the History Stack
---------------------------


Now that the form is submitted for every key stroke, if we type the characters "seba" and then delete them with backspace, we end up with 7 new entries in the stack 😂. We definitely don't want this


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/23.webp)We can avoid this by *replacing* the current entry in the history stack with the next page, instead of pushing into it.


👉 **Use `replace` in `submit`**



```
// existing code

export default function Root() {
  // existing code

  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        <div>
          <Form id="search-form" role="search">
            <input
              id="q"
              // existing code
              onChange={(event) => {
                const isFirstSearch = q == null;
                submit(event.currentTarget.form, {
                  replace: !isFirstSearch,
                });
              }}
            />
            {/* existing code */}
          </Form>
          {/* existing code */}
        </div>
        {/* existing code */}
      </div>
      {/* existing code */}
    </>
  );
}

```

We only want to replace search results, not the page before we started searching, so we do a quick check if this is the first search or not and then decide to replace.


Each key stroke no longer creates new entries, so the user can click back out of the search results without having to click it 7 times 😅.



Mutations Without Navigation
-----------------------------


So far all of our mutations (the times we change data) have used forms that navigate, creating new entries in the history stack. While these user flows are common, it's equally as common to want to change data *without* causing a navigation.


For these cases, we have the [`useFetcher`](../hooks/use-fetcher) hook. It allows us to communicate with loaders and actions without causing a navigation.


The ★ button on the contact page makes sense for this. We aren't creating or deleting a new record, we don't want to change pages, we simply want to change the data on the page we're looking at.


👉 **Change the `<Favorite>` form to a fetcher form**



```
import {
  useLoaderData,
  Form,
  useFetcher,
} from "react-router-dom";

// existing code

function Favorite({ contact }) {
  const fetcher = useFetcher();
  let favorite = contact.favorite;

  return (
    <fetcher.Form method="post">
      <button
        name="favorite"
        value={favorite ? "false" : "true"}
        aria-label={
          favorite
            ? "Remove from favorites"
            : "Add to favorites"
        }
      >
        {favorite ? "★" : "☆"}
      </button>
    </fetcher.Form>
  );
}

```

Might want to take a look at that form while we're here. As always, our form has fields with a `name` prop. This form will send [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) with a `favorite` key that's either `"true" | "false"`. Since it's got `method="post"` it will call the action. Since there is no `<fetcher.Form action="...">` prop, it will post to the route where the form is rendered.


👉 **Create the action**



```
// existing code
import { getContact, updateContact } from "../contacts";

export async function action({ request, params }) {
  let formData = await request.formData();
  return updateContact(params.contactId, {
    favorite: formData.get("favorite") === "true",
  });
}

export default function Contact() {
  // existing code
}

```

Pretty simple. Pull the form data off the request and send it to the data model.


👉 **Configure the route's new action**



```
// existing code
import Contact, {
  loader as contactLoader,
  action as contactAction,
} from "./routes/contact";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    action: rootAction,
    children: [
      { index: true, element: <Index /> },
      {
        path: "contacts/:contactId",
        element: <Contact />,
        loader: contactLoader,
        action: contactAction,
      },
      /* existing code */
    ],
  },
]);

```

Alright, we're ready to click the star next to the user's name!


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/24.webp)Check that out, both stars automatically update. Our new `<fetcher.Form method="post">` works almost exactly like a the `<Form>` we've been using: it calls the action and then all data is revalidated automatically--even your errors will be caught the same way.


There is one key difference though, it's not a navigation--the URL doesn't change, the history stack is unaffected.



Optimistic UI
--------------


You probably noticed the app felt kind of unresponsive when we clicked the the favorite button from the last section. Once again, we added some network latency because you're going to have it in the real world!


To give the user some feedback, we could put the star into a loading state with [`fetcher.state`](../hooks/use-fetcher#fetcherstate) (a lot like `navigation.state` from before), but we can do something even better this time. We can use a strategy called "optimistic UI"


The fetcher knows the form data being submitted to the action, so it's available to you on `fetcher.formData`. We'll use that to immediately update the star's state, even though the network hasn't finished. If the update eventually fails, the UI will revert to the real data.


👉 **Read the optimistic value from `fetcher.formData`**



```
// existing code

function Favorite({ contact }) {
  const fetcher = useFetcher();

  let favorite = contact.favorite;
  if (fetcher.formData) {
    favorite = fetcher.formData.get("favorite") === "true";
  }

  return (
    <fetcher.Form method="post">
      <button
        name="favorite"
        value={favorite ? "false" : "true"}
        aria-label={
          favorite
            ? "Remove from favorites"
            : "Add to favorites"
        }
      >
        {favorite ? "★" : "☆"}
      </button>
    </fetcher.Form>
  );
}

```

If you click the button now you should see the star *immediately* change to the new state. Instead of always rendering the actual data, we check if the fetcher has any `formData` being submitted, if so, we'll use that instead. When the action is done, the `fetcher.formData` will no longer exist and we're back to using the actual data. So even if you write bugs in your optimistic UI code, it'll eventually go back to the correct state 🥹



Not Found Data
---------------


What happens if the contact we're trying load doesn't exist?


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/25.webp)Our root [`errorElement`](../route/error-element) is catching this unexpected error as we try to render a `null` contact. Nice the error was properly handled, but we can do better!


Whenever you have an expected error case in a loader or action–like the data not existing–you can `throw`. The call stack will break, React Router will catch it, and the error path is rendered instead. We won't even try to render a `null` contact.


👉 **Throw a 404 response in the loader**



```
export async function loader({ params }) {
  const contact = await getContact(params.contactId);
  if (!contact) {
    throw new Response("", {
      status: 404,
      statusText: "Not Found",
    });
  }
  return contact;
}

```

![](https://reactrouterdotcom.fly.dev/_docs/tutorial/27.webp)Instead of hitting a render error with `Cannot read properties of null`, we avoid the component completely and render the error path instead, telling the user something more specific.


This keeps your happy paths, happy. Your route elements don't need to concern themselves with error and loading states.



Pathless Routes
----------------


One last thing. The last error page we saw would be better if it rendered inside the root outlet, instead of the whole page. In fact, every error in all of our child routes would be better in the outlet, then the user has more options than hitting refresh.


We'd like it to look like this:


![](https://reactrouterdotcom.fly.dev/_docs/tutorial/26.webp)We could add the error element to every one of the child routes but, since it's all the same error page, this isn't recommended.


There's a cleaner way. Routes can be used *without* a path, which lets them participate in the UI layout without requiring new path segments in the URL. Check it out:


👉 **Wrap the child routes in a pathless route**



```
createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    loader: rootLoader,
    action: rootAction,
    errorElement: <ErrorPage />,
    children: [
      {
        errorElement: <ErrorPage />,
        children: [
          { index: true, element: <Index /> },
          {
            path: "contacts/:contactId",
            element: <Contact />,
            loader: contactLoader,
            action: contactAction,
          },
          /* the rest of the routes */
        ],
      },
    ],
  },
]);

```

When any errors are thrown in the child routes, our new pathless route will catch it and render, preserving the root route's UI!



JSX Routes
-----------


And for our final trick, many folks prefer to configure their routes with JSX. You can do that with `createRoutesFromElements`. There is no functional difference between JSX or objects when configuring your routes, it's simply a stylistic preference.



```
import {
  createRoutesFromElements,
  createBrowserRouter,
} from "react-router-dom";

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route
      path="/"
      element={<Root />}
      loader={rootLoader}
      action={rootAction}
      errorElement={<ErrorPage />}
    >
      <Route errorElement={<ErrorPage />}>
        <Route index element={<Index />} />
        <Route
          path="contacts/:contactId"
          element={<Contact />}
          loader={contactLoader}
          action={contactAction}
        />
        <Route
          path="contacts/:contactId/edit"
          element={<EditContact />}
          loader={contactLoader}
          action={editAction}
        />
        <Route
          path="contacts/:contactId/destroy"
          action={destroyAction}
        />
      </Route>
    </Route>
  )
);

```



---


That's it! Thanks for giving React Router a shot. We hope this tutorial gives you a solid start to build great user experiences. There's a lot more you can do with React Router, so make sure to check out all the APIs 😀



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/start/tutorial>

`Location`
===========


The term "location" in React Router refers to [the `Location` interface](https://github.com/remix-run/history/blob/main/docs/api-reference.md#location) from the [history](https://github.com/remix-run/history) library.


The `history` package is React Router's only dependency and many of the core types in React Router come directly from that library including `Location`, `To`, `Path`, and others. You can read more about the history library in [its documentation](https://github.com/remix-run/history/tree/main/docs).



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/location>

`matchRoutes`
==============


 Type declaration
```
declare function matchRoutes(
  routes: RouteObject[],
  location: Partial<Location> | string,
  basename?: string
): RouteMatch[] | null;

interface RouteMatch<ParamKey extends string = string> {
  params: Params<ParamKey>;
  pathname: string;
  route: RouteObject;
}

```
`matchRoutes` runs the route matching algorithm for a set of routes against a given [`location`](location) to see which routes (if any) match. If it finds a match, an array of `RouteMatch` objects is returned, one for each route that matched.


This is the heart of React Router's matching algorithm. It is used internally by [`useRoutes`](../hooks/use-routes) and the [`<Routes>` component](../components/routes) to determine which routes match the current location. It can also be useful in some situations where you want to manually match a set of routes.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/match-routes>

`isRouteErrorResponse`
=======================


This returns `true` if a [route error](../hooks/use-route-error) is a *route error response*.



```
import { isRouteErrorResponse } from "react-router-dom";

function ErrorBoundary() {
  const error = useRouteError();
  if (isRouteErrorResponse(error)) {
    return (
      <div>
        <h1>Oops!</h1>
        <h2>{error.status}</h2>
        <p>{error.statusText}</p>
        {error.data?.message && <p>{error.data.message}</p>}
      </div>
    );
  } else {
    return <div>Oops</div>;
  }
}

```

When a response is thrown from an action or loader, it will be unwrapped into an `ErrorResponse` so that your component doesn't have to deal with the complexity of unwrapping it (which would require React state and effects to deal with the promise returned from `res.json()`)



```
import { json } from "react-router-dom";

<Route
  errorElement={<ErrorBoundary />}
  action={() => {
    throw json(
      { message: "email is required" },
      { status: 400 }
    );
  }}
/>;

function ErrorBoundary() {
  const error = useRouteError();
  if (isRouteErrorResponse(error)) {
    error.status; // 400
    error.data; // { "message: "email is required" }
  }
}

```

If the user visits a route that does not match any routes in the app, React Router itself will throw a 404 response.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/is-route-error-response>

`createRoutesFromElements`
===========================


`createRoutesFromElements` is a helper that creates route objects from `<Route>` elements. It's useful if you prefer to create your routes as JSX instead of objects.



```
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";

// You can do this:
const router = createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<Root />}>
      <Route path="dashboard" element={<Dashboard />} />
      <Route path="about" element={<About />} />
    </Route>
  )
);

// Instead of this:
const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        path: "dashboard",
        element: <Dashboard />,
      },
      {
        path: "about",
        element: <About />,
      },
    ],
  },
]);

```

It's also used internally by [`<Routes>`](../components/routes) to generate a route objects from its [`<Route>`](../components/route) children.



Type declaration
-----------------



```
declare function createRoutesFromElements(
  children: React.ReactNode
): RouteObject[];

interface RouteObject {
  caseSensitive?: boolean;
  children?: RouteObject[];
  element?: React.ReactNode;
  index?: boolean;
  path?: string;
}

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/create-routes-from-elements>

`generatePath`
===============


 Type declaration
```
declare function generatePath<Path extends string>(
  path: Path,
  params?: {
    [key in PathParams<Path>]: string;
  }
): string;

```
`generatePath` interpolates a set of params into a route path string with `:id` and `*` placeholders. This can be useful when you want to eliminate placeholders from a route path so it matches statically instead of using a dynamic parameter.



```
generatePath("/users/:id", { id: "42" }); // "/users/42"
generatePath("/files/:type/*", {
  type: "img",
  "*": "cat.jpg",
}); // "/files/img/cat.jpg"

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/generate-path>

`matchPath`
============


 Type declaration
```
declare function matchPath<
  ParamKey extends string = string
>(
  pattern: PathPattern | string,
  pathname: string
): PathMatch<ParamKey> | null;

interface PathMatch<ParamKey extends string = string> {
  params: Params<ParamKey>;
  pathname: string;
  pattern: PathPattern;
}

interface PathPattern {
  path: string;
  caseSensitive?: boolean;
  end?: boolean;
}

```
`matchPath` matches a route path pattern against a URL pathname and returns information about the match. This is useful whenever you need to manually run the router's matching algorithm to determine if a route path matches or not. It returns `null` if the pattern does not match the given pathname.


The [`useMatch` hook](../hooks/use-match) uses this function internally to match a route path relative to the current location.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/match-path>

`redirect`
===========


Because you can return or throw responses in loaders and actions, you can use `redirect` to redirect to another route.



```
import { redirect } from "react-router-dom";

const loader = async () => {
  const user = await getUser();
  if (!user) {
    return redirect("/login");
  }
};

```

It's really just a shortcut for this:



```
new Response("", {
  status: 302,
  headers: {
    Location: someUrl,
  },
});

```

It's recommended to use `redirect` in loaders and actions rather than `useNavigate` in your components when the redirect is in response to data.


See also:


* [Returning Responses from Loaders](../route/loader#returning-responses)



Type Declaration
-----------------



```
type RedirectFunction = (
  url: string,
  init?: number | ResponseInit
) => Response;

```


`url`
------


The URL to redirect to.



```
redirect("/login");

```


`init`
-------


The [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response) options to be used in the response.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/fetch/redirect>

`json`
=======


A shortcut for:



```
new Response(JSON.stringify(someValue), {
  headers: {
    "Content-Type": "application/json; utf-8",
  },
});

```

Typically used in loaders:



```
import { json } from "react-router-dom";

const loader = async () => {
  const data = getSomeData();
  return json(data);
};

```

See also:


* [Returning Responses from Loaders](../route/loader#returning-responses)



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/fetch/json>

Working With FormData
======================


TODO: This document is a stub


A common trick is to turn the entire formData into an object with [`Object.fromEntries`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries):



```
const data = Object.fromEntries(await request.formData());
data.songTitle;
data.lyrics;

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/guides/form-data>

`createSearchParams`
=====================


 Type declaration
```
declare function createSearchParams(
  init?: URLSearchParamsInit
): URLSearchParams;

```
`createSearchParams` is a thin wrapper around [`new URLSearchParams(init)`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams) that adds support for using objects with array values. This is the same function that `useSearchParams` uses internally for creating `URLSearchParams` objects from `URLSearchParamsInit` values.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/create-search-params>

`renderMatches`
================


 Type declaration
```
declare function renderMatches(
  matches: RouteMatch[] | null
): React.ReactElement | null;

```
`renderMatches` renders the result of `matchRoutes()` into a React element.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/render-matches>

`resolvePath`
==============


 Type declaration
```
declare function resolvePath(
  to: To,
  fromPathname?: string
): Path;

type To = string | Partial<Path>;

interface Path {
  pathname: string;
  search: string;
  hash: string;
}

```
`resolvePath` resolves a given `To` value into an actual `Path` object with an absolute `pathname`. This is useful whenever you need to know the exact path for a relative `To` value. For example, the `<Link>` component uses this function to know the actual URL it points to.


The [`useResolvedPath` hook](../hooks/use-resolved-path) uses `resolvePath` internally to resolve the pathname. If `to` contains a pathname, it is resolved against the current route pathname. Otherwise, it is resolved against the current URL (`location.pathname`).



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/utils/resolve-path>

Server-Side Rendering
======================


This doc needs updates for 6.4 and only applies to <=6.3


The most basic server rendering in React Router is pretty straightforward. However, there's a lot more to consider than just getting the right routes to render. Here's an incomplete list of things you'll need to handle:


* Bundling your code for the server and the browser
* Not bundling server-only code into the browser bundles
* Code splitting that works on the server and in the browser
* Server Side data loading so you actually have something to render
* Data loading strategies that work on the client and server
* Handling code splitting in the server and client
* Proper HTTP status codes and redirects
* Environment variables and secrets
* Deployment


Setting all of this up well can be pretty involved but is worth the performance and UX characteristics you can only get when server rendering.


If you want to server render your React Router app, we highly recommend you use [Remix](https://remix.run). This is another project of ours that's built on top of React Router and handles all of the things mentioned above and more. Give it a shot!


If you want to tackle it on your own, you'll need to use `<StaticRouter>` on the server.


First you'll need some sort of "app" or "root" component that gets rendered on the server and in the browser:



```
export default function App() {
  return (
    <html>
      <head>
        <title>Server Rendered App</title>
      </head>
      <body>
        <Routes>
          <Route path="/" element={<div>Home</div>} />
          <Route path="/about" element={<div>About</div>} />
        </Routes>
        <script src="/build/client.entry.js" />
      </body>
    </html>
  );
}

```

Here's a simple express server that renders the app on the server. Note the use of `StaticRouter`.



```
import express from "express";
import ReactDOMServer from "react-dom/server";
import { StaticRouter } from "react-router-dom/server";
import App from "./App";

let app = express();

app.get("*", (req, res) => {
  let html = ReactDOMServer.renderToString(
    <StaticRouter location={req.url}>
      <App />
    </StaticRouter>
  );
  res.send("<!DOCTYPE html>" + html);
});

app.listen(3000);

```

And finally, you'll need a similar file to "hydrate" the app with your JavaScript bundle that includes the very same `App` component. Note the use of `BrowserRouter` instead of `StaticRouter`.



```
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";

ReactDOM.hydrate(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.documentElement
);

```

The only real differences from the client entry are:


* `StaticRouter` instead of `BrowserRouter`
* passing the URL from the server to `<StaticRouter url>`
* Using `ReactDOMServer.renderToString` instead of `ReactDOM.render`.


Some parts you'll need to do yourself for this to work:


* How to bundle the code to work in the browser and server
* How to know where the client entry is for `<script>` in the `<App>` component.
* Figuring out data loading (especially for the `<title>`).


Again, we recommend you give [Remix](https://remix.run) a look. It's the best way to server render a React Router app--and perhaps the best way to build any React app 😉.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/guides/ssr>

Deferred Data Guide
====================



The problem
------------


Imagine a scenario where one of your routes' loaders needs to retrieve some data that for one reason or another is quite slow. For example, let's say you're showing the user the location of a package that's being delivered to their home:



```
import { json, useLoaderData } from "react-router-dom";
import { getPackageLocation } from "./api/packages";

async function loader({ params }) {
  const packageLocation = await getPackageLocation(
    params.packageId
  );

  return json({ packageLocation });
}

function PackageRoute() {
  const data = useLoaderData();
  const { packageLocation } = data;

  return (
    <main>
      <h1>Let's locate your package</h1>
      <p>
        Your package is at {packageLocation.latitude} lat
        and {packageLocation.longitude} long.
      </p>
    </main>
  );
}

```

We'll assume that `getPackageLocation` is slow. This will lead to initial page load times and transitions to that route to take as long as the slowest bit of data. There are a few things you can do to optimize this and improve the user experience:


* Speed up the slow thing (😅).
* Parallelize data loading with `Promise.all` (we have nothing to parallelize in our example, but it might help a bit in other situations).
* Add a global transition spinner (helps a bit with UX).
* Add a localized skeleton UI (helps a bit with UX).


If these approaches don't work well, then you may feel forced to move the slow data out of the `loader` into a component fetch (and show a skeleton fallback UI while loading). In this case you'd render the fallback UI on mount and fire off the fetch for the data. This is actually not so terrible from a DX standpoint thanks to [`useFetcher`](../hooks/use-fetcher). And from a UX standpoint this improves the loading experience for both client-side transitions as well as initial page load. So it does seem to solve the problem.


But it's still sub optimal in most cases (especially if you're code-splitting route components) for two reasons:


1. Client-side fetching puts your data request on a waterfall: document -> JavaScript -> Lazy Loaded Route -> data fetch
2. Your code can't easily switch between component fetching and route fetching (more on this later).



The solution
-------------


React Router takes advantage of React 18's Suspense for data fetching using the [`defer` Response](../fetch/defer) utility and [`<Await />`](../components/await) component / [`useAsyncValue`](../hooks/use-async-data) hook. By using these APIs, you can solve both of these problems:


1. Your data is no longer on a waterfall: document -> JavaScript -> Lazy Loaded Route & data (in parallel)
2. Your can easily switch between rendering the fallback and waiting for the data


Let's take a dive into how to accomplish this.


### 
Using `defer`


Start by adding `<Await />` for your slow data requests where you'd rather render a fallback UI. Let's do that for our example above:



```
import { defer, useLoaderData } from "react-router-dom";
import { getPackageLocation } from "./api/packages";

async function loader({ params }) {
  const packageLocationPromise = getPackageLocation(
    params.packageId
  );

  return defer({
    packageLocation: packageLocationPromise,
  });
}

export default function PackageRoute() {
  const data = useLoaderData();

  return (
    <main>
      <h1>Let's locate your package</h1>
      <React.Suspense
        fallback={<p>Loading package location...</p>}
      >
        <Await
          resolve={data.packageLocation}
          errorElement={
            <p>Error loading package location!</p>
          }
        >
          {(packageLocation) => (
            <p>
              Your package is at {packageLocation.latitude}{" "}
              lat and {packageLocation.longitude} long.
            </p>
          )}
        </Await>
      </React.Suspense>
    </main>
  );
}

```

 Alternatively, you can use the `useAsyncValue` hook:If you're not jazzed about bringing back render props, you can use a hook, but you'll have to break things out into another component:



```
export default function PackageRoute() {
  const data = useLoaderData();

  return (
    <main>
      <h1>Let's locate your package</h1>
      <React.Suspense
        fallback={<p>Loading package location...</p>}
      >
        <Await
          resolve={data.packageLocation}
          errorElement={
            <p>Error loading package location!</p>
          }
        >
          <PackageLocation />
        </Await>
      </React.Suspense>
    </main>
  );
}

function PackageLocation() {
  const packageLocation = useAsyncValue();
  return (
    <p>
      Your package is at {packageLocation.latitude} lat and{" "}
      {packageLocation.longitude} long.
    </p>
  );
}

```

Evaluating the solution
------------------------


So rather than waiting for the component before we can trigger the fetch request, we start the request for the slow data as soon as the user starts the transition to the new route. This can significantly speed up the user experience for slower networks.


Additionally, the API that React Router exposes for this is extremely ergonomic. You can literally switch between whether something is going to be deferred or not based on whether you include the `await` keyword:



```
return defer({
  // not deferred:
  packageLocation: await packageLocationPromise,
  // deferred:
  packageLocation: packageLocationPromise,
});

```

Because of this, you can A/B test deferring, or even determine whether to defer based on the user or data being requested:



```
async function loader({ request, params }) {
  const packageLocationPromise = getPackageLocation(
    params.packageId
  );
  const shouldDefer = shouldDeferPackageLocation(
    request,
    params.packageId
  );

  return defer({
    packageLocation: shouldDefer
      ? packageLocationPromise
      : await packageLocationPromise,
  });
}

```

That `shouldDeferPackageLocation` could be implemented to check the user making the request, whether the package location data is in a cache, the status of an A/B test, or whatever else you want. This is pretty sweet 🍭



FAQ
----


### 
Why not defer everything by default?


The React Router defer API is another lever React Router offers to give you a nice way to choose between trade-offs. Do you want the page to render more quickly? Defer stuff. Do you want a lower CLS (Content Layout Shift)? Don't defer stuff. You want a faster render, but also want a lower CLS? Defer just the slow and unimportant stuff.


It's all trade-offs, and what's neat about the API design is that it's well suited for you to do easy experimentation to see which trade-offs lead to better results for your real-world key indicators.


### 
When does the `<Suspense/>` fallback render?


The `<Await />` component will only throw the promise up the `<Suspense>` boundary on the initial render of the `<Await />` component with an unsettled promise. It will not re-render the fallback if props change. Effectively, this means that you *will not* get a fallback rendered when a user submits a form and loader data is revalidated. You *will* get a fallback rendered when the user navigates to the same route with different params (in the context of our above example, if the user selects from a list of packages on the left to find their location on the right).


This may feel counter-intuitive at first, but stay with us, we really thought this through and it's important that it works this way. Let's imagine a world without the deferred API. For those scenarios you're probably going to want to implement Optimistic UI for form submissions/revalidation.


When you decide you'd like to try the trade-offs of `defer`, we don't want you to have to change or remove those optimizations because we want you to be able to easily switch between deferring some data and not deferring it. So, we ensure that your existing optimistic states work the same way. If we didn't do this, then you could experience what we call "Popcorn UI" where submissions of data trigger the fallback loading state instead of the optimistic UI you'd worked hard on.


So just keep this in mind: **Deferred is 100% only about the initial load of a route and it's params.**



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/guides/deferred>

Contributing to React Router
=============================


Thanks for contributing, you rock!


When it comes to open source, there are many different kinds of contributions that can be made, all of which are valuable. Here are a few guidelines that should help you as you prepare your contribution.



Setup
------


Before you can contribute to the codebase, you will need to fork the repo. This will look a bit different depending on what type of contribution you are making:


* All new features, bug-fixes, or **anything that touches `react-router` code** should be branched off of and merged into the `dev` branch
* Changes that only touch documentation can be branched off of and merged into the `main` branch


The following steps will get you set up to contribute changes to this repo:


1. Fork the repo (click the `Fork` button at the top right of [this page](https://github.com/remix-run/react-router))
2. Clone your fork locally



```
# in a terminal, cd to parent directory where you want your clone to be, then
git clone https://github.com/<your_github_username>/react-router.git
cd react-router

# if you are making *any* code changes, make sure to checkout the dev branch
git checkout dev

```

3. Install dependencies and build. React Router uses [`yarn` (version 1)](https://classic.yarnpkg.com/lang/en/docs/install), so you should too. If you install using `npm`, unnecessary `package-lock.json` files will be generated.



Think You Found a Bug?
-----------------------


Please conform to the issue template and provide a clear path to reproduction with a code example. Best is a pull request with a failing test. Next best is a link to CodeSandbox or repository that illustrates the bug.



Proposing New or Changed API?
------------------------------


Please provide thoughtful comments and some sample code that show what you'd like to do with React Router in your app. It helps the conversation if you can show us how you're limited by the current API first before jumping to a conclusion about what needs to be changed and/or added.


We have learned by experience that small APIs are usually better, so we may be a little reluctant to add something new unless there's an obvious limitation with the current API. That being said, we are always anxious to hear about cases that we just haven't considered before, so please don't be shy! :)



Issue Not Getting Attention?
-----------------------------


If you need a bug fixed and nobody is fixing it, your best bet is to provide a fix for it and make a [pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request). Open source code belongs to all of us, and it's all of our responsibility to push it forward.



Making a Pull Request?
-----------------------


Pull requests need only the approval of two or more collaborators to be merged; when the PR author is a collaborator, that counts as one.


When creating the PR in GitHub, make sure that you set the base to the correct branch. If you are submitting a PR that touches any code, this should be the `dev` branch. You set the base in GitHub when authoring the PR with the dropdown below the "Compare changes" heading: ![]


### 
Tests


All commits that fix bugs or add features need a test.


`<blink>`Do not merge code without tests!`</blink>`


### 
Docs + Examples


All commits that change or add to the API must be done in a pull request that also updates all relevant examples and docs.



Development
------------


### 
Packages


React Router uses a monorepo to host code for multiple packages. These packages live in the `packages` directory.


We use [Yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) to manage installation of dependencies and running various scripts. To get everything installed, make sure you have [Yarn (version 1) installed](https://classic.yarnpkg.com/lang/en/docs/install), and then run `yarn` or `yarn install` from the repo root.


### 
Building


Calling `yarn build` from the root directory will run the build, which should take only a few seconds. It's important to build all the packages together because `react-router-dom` and `react-router-native` both use `react-router` as a dependency.


### 
Testing


Before running the tests, you need to run a build. After you build, running `yarn test` from the root directory will run **every** package's tests. If you want to run tests for a specific package, use `yarn test --projects packages/<package-name>`:



```
# Test all packages
yarn test

# Test only react-router-dom
yarn test --projects packages/react-router-dom

```


Repository Branching
---------------------


This repo maintains separate branches for different purposes. They will look something like this:


There may be other branches for various features and experimentation, but all of the magic happens from these branches.



New Releases
-------------


When it's time to cut a new release, we follow a process based on our branching strategy depending on the type of release.


### 
`react-router@next` Releases


We create experimental releases from the current state of the `dev` branch. They can be installed by using the `@next` tag:



```
yarn add react-router-dom@next
# or
npm install react-router-dom@next

```

These releases will be automated as PRs are merged into the `dev` branch.


### 
Latest Major Releases



```
# Start from the dev branch.
git checkout dev

# Merge the main branch into dev to ensure that any hotfixes and
# docs updates are available in the release.
git merge main

# Create a new release branch from dev.
git checkout -b release/v6.1.0

# Create a new tag and update version references throughout the
# codebase.
yarn run version minor # | "patch" | "major"

# Push the release branch along with the new release tag.
git push origin release/v6.1.0 --follow-tags

# Wait for GitHub actions to run all tests. If the tests pass, the
# release is ready to go! Merge the release branch into main and dev.
git checkout main
git merge release/v6.1.0
git checkout dev
git merge release/v6.1.0

# The release branch can now be deleted.
git branch -D release/v6.1.0
git push origin --delete release/v6.1.0

# Now go to GitHub and create the release from the new tag. Let
# GitHub Actions take care of the rest!

```

### 
Hot-fix Releases


Sometimes we have a crucial bug that needs to be patched right away. If the bug affects the latest release, we can create a new version directly from `main` (or the relevant major release branch where the bug exists):



```
# From the main branch, make sure to run the build and all tests
# before creating a new release.
yarn && yarn build && yarn test

# Assuming the tests pass, create the release tag and update
# version references throughout the codebase.
yarn run version patch

# Push changes along with the new release tag.
git push origin main --follow-tags

# In GitHub, create the release from the new tag and it will be
# published via GitHub actions

# When the hot-fix is done, merge the changes into dev and clean
# up conflicts as needed.
git checkout dev
git merge main
git push origin dev

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/guides/contributing>

Index Query Param
==================


You may find a wild `?index` appear in the URL of your app when submitting forms.


Because of nested routes, multiple routes in your route hierarchy can match the URL. Unlike navigations where all matching route loaders are called to build up the UI, when a form is submitted *only one action is called*.


Because index routes share the same URL as their parent, the `?index` param lets you disambiguate between the two.


For example, consider the following router and forms:



```
createBrowserRouter([
  {
    path: "/projects",
    element: <ProjectsLayout />,
    action: ProjectsLayout.action,
    children: [
      {
        index: true,
        element: <ProjectsIndex />,
        action: ProjectsPage.action,
      },
    ],
  },
]);

<Form method="post" action="/projects" />;
<Form method="post" action="/projects?index" />;

```

The `?index` param will submit to the index route, the action without the index param will submit to the parent route.


When a `<Form>` is rendered in an index route without an `action`, the `?index` param will automatically be appended so that the form posts to the index route. The following form, when submitted, will post to `/projects?index` because it is rendered in the context of the projects index route:



```
function ProjectsIndex() {
  return <Form method="post" />;
}

```

If you moved the code to the `ProjectsLayout` route, it would instead post to `/projects`.


This applies to `<Form>` and all of its cousins:



```
let submit = useSubmit();
submit({}, { action: "/projects" });
submit({}, { action: "/projects?index" });

let fetcher = useFetcher();
fetcher.submit({}, { action: "/projects" });
fetcher.submit({}, { action: "/projects?index" });
<fetcher.Form action="/projects" />;
<fetcher.Form action="/projects?index" />;
<fetcher.Form />; // defaults to the route in context

```


 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/guides/index-search-param>

Index Route
============


TODO



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/guides/index-route>

Data Library Integration
=========================


Since the release of v6.4 some folks wonder if React Router is attempting to replace libraries like [React Query](https://tanstack.com/query/v4/), [useSwr](https://swr.vercel.app/), etc.


The answer is "nope!".


React Router's data APIs are about *when* to load, mutate, and revalidate data, but not *how* to do it. It's about the data lifecycle, not the actual implementation of data fetching, mutation, storage, and caching.


Considering that `<a href>` and `<form action>` are both navigation events, and both coupled to data (what data to show or what data to change), it makes sense that a client side router would help you with the *navigation state* of both elements. But the actual data implementation is up to you.


The examples here were adapted from [TkDodo's blog](https://tkdodo.eu/blog/react-query-meets-react-router), thank you for the great post!



Loading Data
-------------


Instead of loading data in components, you use your data abstractions inside of loaders. Note that this loading happens outside of the React render lifecycle, so you can't use hooks like React Query's `useQuery`, you'll need to use the query client's methods directly.



```
import { queryClient } from "./query-client";

export const loader = ({ params }) => {
  return queryClient.fetchQuery(queryKey, queryFn, {
    staleTime: 10000,
  });
};

```

If the query client throws errors correctly, then React Router's [`errorElement`](../route/error-element) will work the same.


Of course, you can use all of the features of the data library, like caching. Caching your data ensures that when the user clicks the back button to a page you've already seen, the data is loaded from the cache immediately. Sometimes caching is the right choice, sometimes you always want it fresh, but that's not a decision within the scope of React Router's data APIs.


React Router only retains the *current page's loaderData*. If users click "back", all loaders are called again. Without a data caching library like React Query (or HTTP cache headers on your JSON API to use the browser's own HTTP cache), your app will refetch all of the data again.


In this way, React Router is about *timing*, where React Query is about *caching*.



Accessing Data in Components
-----------------------------


While React Router's `useLoaderData` returns whatever you returned from your loader, you can use your data abstraction's hooks instead to get access to the full feature set of that package.



```
export default function SomeRouteComponent() {
- const data = useLoaderData();
+ const { data } = useQuery(someQueryKey);
}

```


Invalidating Data in Mutations
-------------------------------


Because most of these library's have some mechanism for caching, you'll need to invalidate those caches at some point.


The perfect place to invalidate those caches is in a React Router [action](../route/action).



```
import { queryClient } from "./query-client";

export const action = async ({ request, params }) => {
  const formData = await request.formData();
  const updates = Object.fromEntries(formData);
  await updateContact(params.contactId, updates);
  await queryClient.invalidateQueries(["contacts"]);
  return redirect(`/contacts/${params.contactId}`);
};

```


Usage with `defer`
-------------------


You can similarly take advantage of the deferred APIs:



```
function loader() {
  return defer({
    // no await!
    someData: queryClient.fetchQuery("someKey", fn),
  });
}

function Comp() {
  // *do* useLoaderData for promise
  const { someData } = useLoaderData();
  return (
    <div>
      <h1>Something</h1>
      <Await
        resolve={someData}
        errorElement={<div>Oops!</div>}
      >
        <SomeView />
      </Await>
    </div>
  );
}

function SomeView() {
  // instead of accessing with useAsyncValue
  // const someData = useAsyncValue();
  // `useQuery` as usual
  const { data } = useQuery("someKey");
  // ...
}

```


The Overlap
------------


Hooks like `useQuery` often return pending and error states you can use to branch your UI. With React Router, you can keep all of that branching out of your happy path components and rely on [`errorElement`](../route/error-element), [`useNavigation`](../hooks/use-navigation), and [`Await`](../components/await) instead.



Conclusion
-----------


With all of these APIs working together, you can now use [`useNavigation`](../hooks/use-navigation) from React Router to build pending states, optimistic UI, and more. Use React Router for timing of data loading, mutations, and navigation state, then use libraries like React Query for the actual implementation of loading, invalidating, storage, and caching.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/guides/data-libs>

`useRouteLoaderData`
=====================


This hook makes the data at any currently rendered route available anywhere in the tree. This is useful for components deep in the tree needing data from routes much farther up, as well as parent routes needing the data of child routes deeper in the tree.



```
import { useRouteLoaderData } from "react-router-dom";

function SomeComp() {
  const user = useRouteLoaderData("root");
  // ...
}

```

React Router stores data internally with deterministic, auto-generated route ids, but you can supply your own route id to make this hook much easier to work with. Consider a router with a route that defines an id:



```
createBrowserRouter([
  {
    path: "/",
    loader: () => fetchUser(),
    element: <Root />,
    id: "root",
    children: [
      {
        path: "jobs/:jobId",
        loader: loadJob,
        element: <JobListing />,
      },
    ],
  },
]);

```

Now the user is available anywhere else in the app.



```
const user = useRouteLoaderData("root");

```

The only data available is the routes that are currently rendered. If you ask for data from a route that is not currently rendered, the hook will return `undefined`.



 © React Training 2015-2019  
© Remix Software 2020-2022  
Licensed under the MIT License (MIT).  

<https://reactrouterdotcom.fly.dev/docs/en/v6/hooks/use-route-loader-data>

react\_router