react-router Documentation

Declarative routing for React

56,545 stars TypeScript TypeScript 1 file ยท ~4,514 tokens
RAW Doc

1. Project Overview & Quickstart (remix-run/react-router)

File: README.md

npm package build

React Router is a multi-strategy router for React. You can use it maximally as a React framework or minimally as a library with your own architecture.

Packages

Previous Versions


File: docs/community/api-development-strategy.md


title: API Development Strategy

API Development Strategy

React Router is foundational to your application. We want to make sure that upgrading to new major versions is as smooth as possible while still allowing us to adjust and enhance the behavior and API as the React ecosystem advances.

Our strategy and motivations are discussed in more detail in our Future Flags blog post and our Open Governance Model.

Future Flags

When an API changes in a breaking way, it is introduced in a future flag. This allows you to opt-in to one change a time before it becomes the default in the next major version.

  • Without enabling the future flag, nothing changes about your app
  • Enabling the flag changes the behavior for that feature

All current future flags are documented in the Future Changes Guide to help you stay up-to-date.

Unstable Flags

Unstable flags are for features still being designed and developed and made available to our users to help us get it right.

Unstable flags are not recommended for production:

  • they will change without warning and without upgrade paths
  • they will have bugs
  • they aren't documented
  • they may be scrapped completely

When you opt-in to an unstable flag you are becoming a contributor to the project, rather than a user. We appreciate your help, but please be aware of the new role!

Because unstable flags are experimental and not guaranteed to stick around, we ship them in SemVer patch releases because they're not new stable/documented APIs. When an unstable flag stabilizes into a Future Flag, that will be released in a SemVer minor release and will be properly documented and added to the Future Changes Guide.

To learn about current unstable flags, keep an eye on the CHANGELOG.

Example New Feature Flow

The decision flow for a new feature looks something like this:


File: docs/community/contributing.md


title: Contributing

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.

Open Governance Model

Before going any further, please read the Open Governance blog post and document for information on how we handle bugs/issues/feature proposals in React Router.

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, documentation updates, or anything that touches react-router code should 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)

  2. Clone your fork locally

    bash
    # 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
  3. Install dependencies and build. React Router uses pnpm, 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 minimal and runnable reproduction. Best is a pull request with a failing test. Next best is a link to StackBlitz, CodeSandbox, or GitHub repository that illustrates the bug.

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. Open source code belongs to all of us, and it's all of our responsibility to push it forward.

Proposing New or Changed API?

โš ๏ธ Please do not start with a PR for a new feature.

New features need to go through the process outlined in the Open Governance Model and can be started by opening a Proposal Discussion on GitHub. 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! :)

Adding an Example?

Examples can be added directly to the main branch. Create a branch off of your local clone of main. Once you've finished, create a pull request and outline your example.

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 main 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 one or more tests.

Do not merge code without tests!

Change Files

In order to facilitate release notes generation, every PR with a user-facing impact should include one or more change files. You can generate these vis pnpm run changes:add (requires node 24+).

This tool will generate change files in the relevant packages//.changes/ directories. Change files are markdown files with a short description of the change. They should be named using the format <type>.<short-description>.md where type is either patch, minor, major, or unstable. For example:

sh
patch.fix-fetcher-redirects.md
minor.add-some-new-api.md
major.require-node-24.md
unstable.update-unstable-api.md

Code of Conduct/Contributor License Agreement

All contributors must review the review the CLA and sign it by adding their github username to contributors.yml.

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.

Documentation is located in the docs directory. Once changes make their way into the main branch, they will automatically be published to the docs site.

If you want to preview how the changes will look on the docs site, clone the react-router-website repository and follow the instructions in README.md to view your changes locally.

Development

Packages

React Router uses a monorepo to host code for multiple packages. These packages live in the packages directory.

We use pnpm workspaces to manage installation of dependencies and running various scripts. To get everything installed, make sure you have pnpm installed, and then run pnpm install from the repo root.

Building

Calling pnpm 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 the individual packages have dependencies on one another.

Testing

Before running the tests, you need to run a build. After you build, running pnpm test from the root directory will run every package's tests. If you want to run tests for a specific package, use pnpm test packages//:

bash
# Test all packages
pnpm test

# Test only @react-router/dev
pnpm test packages/react-router-dev/

Repository Branching

This repo maintains separate branches for different purposes. They will look something like this:

text
- main   > the most recent release and current docs
- v6     > the most recent code for a specific major release

There may be other branches for various features and experimentation, but all of the magic happens from these branches.

Releases

Please refer to DEVELOPMENT.md for an outline of the release process.


File: docs/api/hooks/useActionData.md


title: useActionData

useActionData

[MODES: framework, data]

Summary

Reference Documentation โ†—

Returns the action data from
the most recent POST navigation form submission or undefined if there
hasn't been one.

tsx
import { Form, useActionData } from "react-router";

export async function action({ request }) {
  const body = await request.formData();
  const name = body.get("visitorsName");
  return { message: `Hello, ${name}` };
}

export default function Invoices() {
  const data = useActionData();
  return (
    <Form method="post">
      
      {data ? data.message : "Waiting..."}
    </Form>
  );
}

Signature

tsx
function useActionData<T = any>(): SerializeFrom<T> | undefined

Returns

The data returned from the route's action
function, or undefined if no action
has been called


File: docs/api/hooks/useAsyncError.md


title: useAsyncError

useAsyncError

[MODES: framework, data]

Summary

Reference Documentation โ†—

Returns the rejection value from the closest <Await>.

tsx
import { Await, useAsyncError } from "react-router";

function ErrorElement() {
  const error = useAsyncError();
  return (
    Uh Oh, something went wrong! {error.message}
  );
}

// somewhere in your app
<Await
  resolve={promiseThatRejects}
  errorElement={<ErrorElement />}
/>;

Signature

tsx
function useAsyncError(): unknown

Returns

The error that was thrown in the nearest Await component


File: docs/api/hooks/useAsyncValue.md


title: useAsyncValue

useAsyncValue

[MODES: framework, data]

Summary

Reference Documentation โ†—

Returns the resolved promise value from the closest <Await>.

tsx
function SomeDescendant() {
  const value = useAsyncValue();
  // ...
}

// somewhere in your app
<Await resolve={somePromise}>
  <SomeDescendant />
</Await>;

Signature

tsx
function useAsyncValue(): unknown

Returns

The resolved value from the nearest Await component


File: docs/api/hooks/useBeforeUnload.md


title: useBeforeUnload

useBeforeUnload

[MODES: framework, data, declarative]

Summary

Reference Documentation โ†—

Set up a callback to be fired on Window's beforeunload event.

Signature

tsx
function useBeforeUnload(
  callback: (event: BeforeUnloadEvent) => any,
  options?: {
    capture?: boolean;
  },
): void

Params

callback

The callback to be called when the beforeunload event is fired.

options.capture

If true, the event will be captured during the capture phase. Defaults to false.

Returns

No return value.

2. Official Technical Reference & Guides (remix-run/react-router-website)

File: README.md

React Router Website!

Contributing

If you want to make a contribution

  • Fork and clone this repo
  • Create a branch
  • Push any changes you make to your branch
  • Open up a PR in this Repo

Setup

First setup your .env file, use .env.example to know what to set.

sh
cp .env.example .env

Install dependencies

sh
pnpm install

Local Development

Now you should be good to go:

sh
pnpm run dev

To preview local changes to the docs folder in the React Router repo, select "local" from the version dropdown menu on the site. Make sure you have the react-router repo cloned locally and LOCAL_REPO_RELATIVE_PATH is pointed to the correct filepath.

We leverage a number of LRUCache's to server-side cache various resources, such as processed markdown from GitHub, that expire at various times (usually after 5 minutes). If you want them to expire immediately for local development, set the NO_CACHE environment variable.

sh
NO_CACHE=1 pnpm run dev

Note that by default this assumes the relative path to your local copy of the React Router docs is ../react-router. This can be configured via LOCAL_REPO_RELATIVE_PATH in your .env file.

Preview

To preview the production build locally:

sh
pnpm run build
pnpm run preview

Deployment

The production server is always in sync with main

sh
git push origin main
open https://reactrouter.com

Pushing the "stage" tag will deploy to staging.

sh
git checkout my/branch

# moves the `stage` tag and pushes it, triggering a deploy
pnpm run push:stage

When you're happy with it, merge your branch into main and push.

CSS Notes

You'll want the tailwind VSCode plugin for sure, the hints are amazing.

The color scheme has various shades but we also have a special "brand" rule for each of our brand colors so we don't have to know the specific number of that color like this: ``.

We want to use Tailwind's default classes as much as possible to avoid a large CSS file. A few things you can do to keep the styles shared:

  • Avoid changing anything but the theme in tailwind.config.js, no special classes, etc.
  • Avoid "inline rules" like color-[#ccc] as much as possible.
  • Silly HTML (like a wrapper div to add padding on a container) is better than one-off css rules.

We use DocSearch by Algolia for our documentation's search. The site is automatically scraped and indexed weekly by the Algolia Crawler.

If the doc search results ever seem outdated or incorrect be sure to check that the crawler isn't blocked. If it is, it might just need to be canceled and restarted to kick things off again. There is also an editor in the Crawler admin that lets you adjust the crawler's script if needed.


File: app/components/_playground/README.md

Visit http://localhost:3000/__components to render the playground.

It's like bootleg storybook so you can build/tweak/play around with components in isolation


File: app/modules/README.md

This folder is for modules that could potentially be published to npm

  • could be used in any Remix app
  • no clue about this actual app
  • no dependency on styling/tailwind etc.
  • ideally has some tests

NOTE: please put them in their own folder (like they would be if the were in node_modules/[the thing]).


File: app/ui/README.md

I don't know what this folder is for, should probably get everything out of here