React Router is a complete routing solution designed specifically for React.js. It painlessly synchronizes the components of your application with the URL, with first-class support for nesting, transitions, and server side rendering.

Contribute on Github.

Router OverviewGuides

To illustrate the problems React Router is going to solve for you, let’s build a small application without it.

Without React Router

var About = React.createClass({
  render: function () {
    return <h2>About</h2>;
  }
});

var Inbox = React.createClass({
  render: function () {
    return <h2>Inbox</h2>;
  }
});

var Home = React.createClass({
  render: function () {
    return <h2>Home</h2>;
  }
});

var App = React.createClass({
  render () {
    var Child;
    switch (this.props.route) {
      case 'about': Child = About; break;
      case 'inbox': Child = Inbox; break;
      default:      Child = Home;
    }

    return (
      <div>
        <h1>App</h1>
        <Child/>
      </div>
    )
  }
});

function render () {
  var route = window.location.hash.substr(1);
  React.render(<App route={route} />, document.body);
}

window.addEventListener('hashchange', render);
render(); // render initially

As the hash portion of the URL changes, App will render a different <Child/> by branching on this.props.route. Pretty straightforward stuff. But it gets complicated fast.

Imagine now that Inbox has some nested UI at a path like inbox/messages/:id and inbox/unread, etc. We'll need to make our url parsing much more intelligent to be able to pass the right information to App, and then to Inbox in order for it to know which URL-mapped child component it should render. We'd then have a branch of components that should be rendered at any given URL. Add a few more of these branches and we'll end up with a lot of code to keep the URL and our application's component hierarchy in sync.

With React Router

Nested URLs and nested component hierarchy are at the heart of React Router. Lets make our routing for our little app declarative. We use JSX for route configuration because we want to define a view hierarchy with properties, so its a pefect fit.

var Router = require('react-router');
var Route = Router.Route;

// declare our routes and their hierarchy
var routes = (
  <Route handler={App}>
    <Route path="about" handler={About}/>
    <Route path="inbox" handler={Inbox}/>
  </Route>
);

Next we need to delete some code from App. We'll replace <Child/> with <RouteHandler/> that functions as the old switch block from before.

var RouteHandler = Router.RouteHandler;

var App = React.createClass({
  render () {
    return (
      <div>
        <h1>App</h1>
        <RouteHandler/>
      </div>
    )
  }
});

Finally we need to listen to the url and render the application.

Router.run(routes, Router.HashLocation, (Root) => {
  React.render(<Root/>, document.body);
});

Root is a component that bakes in the matched component hierarchy making RouteHandler know what to render.

Note that <Route/> components are not ever rendered, they are just configuration objects that the router uses to create an internal tree of routes.

Adding more UI

Alright, now we're ready to nest the inbox messages inside the inbox UI. First we'll make a new Message component and then we'll add the route under inbox so that the UI will nest.

var Message = React.createClass({
  render () {
    return <h3>Message</h3>;
  }
});

var routes = (
  <Route handler={App}>
    <Route path="about" handler={About}/>
    <Route path="inbox" handler={Inbox}>
      <Route path="messages/:id" handler={Message}/>
    </Route>
  </Route>
);

Now visits to urls like inbox/messages/Jkei3c32 will match the new route and nest the UI branch of App -> Inbox -> Message.

Getting the url parameters

We're going to need to know something about the message in order to fetch it from the server. We call the component you hand to a <Route/> a RouteHandler. RouteHandler instances get some useful properties injected into them when you render, particularly the parameters from the dynamic segment of your path. In our case, :id.

var Message = React.createClass({
  componentDidMount: function () {
    // from the path `/inbox/messages/:id`
    var id = this.props.params.id;
    fetchMessage(id, function (err, message) {
      this.setState({ message: message });
    })
  },
  // ...
});

Nested UI and Nested URLs need not be coupled

With React Router, you don't need to nest your UI in order to get a nested URL. Inversely, to get nested UI, you don't need to have nested URLs either.

Lets make a new url at /about/company, but without nesting the UI inside of the About component.

var routes = (
  <Route handler={App}>
    <Route path="about" handler={About}/>
    <Route path="about/company" handler={Company}/>
  </Route>
);

Though our url is nested, the UI of About and Company are siblings.

Now lets go the other way and add the url /archive/messages/:id and have it nested under our inbox UI even though the URL is not nested. We have to do three things for this to work:

  1. Start the path with / to signal that its an absolute path. This won’t “inherit” the parent path the way inbox/messages/:id gets inherited.
  2. Nest the <Route/> under the inbox route to cause the UI to nest.
  3. Ensure you have all the necessary dynamic segments, we only have :id so its pretty easy.
var routes = (
  <Route handler={App}>
    <Route path="inbox" handler={Inbox}>
      <Route path="messages/:id" handler={Message}/>
      <Route path="/archive/messages/:id" handler={Message}/>
    </Route>
  </Route>
);

That's the gist of React Router. Application UIs are boxes inside of boxes inside of boxes; now you can keep those boxes in sync with the URL.

DefaultRouteRoute Configuration

A DefaultRoute will be the matched child route when the parent's path matches exactly.

You'd want to use this to ensures a child RouteHandler is always rendered when there is no child match. Think of it like index.html in a directory of a static html server.

Props

handler

The RouteHandler component you want to be rendered when the route is matched.

name (optional)

The name of the route used when linking or transitioning to the route.

Example

<Route path="/" handler={App}>

  <!--
    When the url is `/`, this route will be active. In other
    words, `Home` will be the `<RouteHandler/>` in `App`.
  -->
  <DefaultRoute handler={Home}/>

  <Route name="about" handler={About}/>
  <Route name="users" handler={Users}>
    <Route name="user" handler={User} path="/user/:id"/>

    <!-- when the url is `/users`, this will be active -->
    <DefaultRoute name="users-index" handler={UsersIndex}/>

  </Route>
</Route>

NotFoundRouteRoute Configuration

A NotFoundRoute is active when the beginning of its parent's path matches the URL but none of its siblings do. It can be found at any level of your hierarchy, allowing you to have a context-aware "not found" screens.

You'd want to use this to handle bad links and users typing invalid urls into the address bar.

Note: This is not intended to be used for when a resource is not found. There is a difference between the router not finding a matched path and a valid URL that results in a resource not being found. The url courses/123 is a valid url and results in a matched route, therefore it was "found" as far as routing is concerned. Then, if we fetch some data and discover that the course 123 does not exist, we do not want to transition to a new route. Just like on the server, you go ahead and serve the url but render different UI (and use a different status code). You shouldn't ever try to transition to a NotFoundRoute.

Props

handler

The RouteHandler component you want to be rendered when the route is matched.

Example

<Route path="/" handler={App}>
  <Route name="course" path="course/:courseId" handler={Course}>
    <Route name="course-dashboard" path="dashboard" handler={Dashboard}/>

    <!-- ie: `/course/123/foo` -->
    <NotFoundRoute handler={CourseRouteNotFound} />
  </Route>

  <!-- ie: `/flkjasdf` -->
  <NotFoundRoute handler={NotFound} />
</Route>

The last NotFoundRoute will render inside the App, the first will render inside of Course.

RedirectRoute Configuration

A Redirect sets up a redirect to another route in your application to maintain old URLs.

Props

from

The path you want to redirect from, including dynamic segments. Defaults to * so you can redirect anything not found to somewhere else.

to

The name of the route you want to redirect to.

params

By default, the parameters will just pass through to the new route, but you can specify them if you need to (usually you shouldn't).

query

By default, the query parameters will just pass through to the new route, but you can specify them if you need to (usually you shouldn't).

Example

<!--
  lets say we want to change from `/profile/123` to `/about/123`
  and redirect `/get-in-touch` to `/contact`
-->
<Route handler={App}>
  <Route name="contact" handler={Contact}/>
  <Route name="about-user" path="about/:userId" handler={UserProfile}/>
  <Route name="course" path="course/:courseId">
    <Route name="course-dashboard" path="dashboard" handler={Dashboard}/>
    <Route name="course-assignments" path="assignments" handler={Assignments}/>
  </Route>

  <!-- `/get-in-touch` -> `/contact` -->
  <Redirect from="get-in-touch" to="contact" />

  <!-- `/profile/123` -> `/about/123` -->
  <Redirect from="profile/:userId" to="about-user" />

  <!-- `/profile/me` -> `/about-user/123` -->
  <Redirect from="profile/me" to="about-user" params={{userId: SESSION.USER_ID}} />
</Route>

Note that the <Redirect/> can be placed anywhere in the route hierarchy, if you'd prefer the redirects to be next to their respective routes, the from path will match the same as a regular route path.

<Route handler={App}>
  <Route name="course" path="course/:courseId">
    <Route name="course-dashboard" path="dashboard" handler={Dashboard}/>
    <!-- /course/123/home -> /course/123/dashboard -->
    <Redirect from="home" to="course-dashboard" />
  </Route>
</Route>

RouteRoute Configuration

A Route is used to declaratively map routes to your application's screen hiearchy.

Props

name (optional)

The unique name of the route, used in the Link component and the router's transition methods.

path (optional)

The path used in the URL. If left undefined, the path will be defined by the name, and if there is no name, will default to /.

Please refer to the Path Matching Guide to learn more about supported path matching syntax.

handler

The RouteHandler component to be rendered when the route is active.

children

Routes can be nested. When a child route path matches, the parent route is also activated. Please refer to the overview since this is a very critical part of the router's design.

ignoreScrollBehavior

When a route or its params change, the router adjusts window scroll position according to the [scrollBehavior][scrollbehavior]. This is generally desirable but you might want to opt-out of scrolling adjustment for a specific route or a group of routes.

If you specify ignoreScrollBehavior, changes in params or any transitions within its children will not adjust scroll position. This can be useful on a search page or in a tabbed interface.

Note that changes in query never adjust scroll position, regardless of the value of this attribute.

Example

<!-- `path` defaults to '/' since no name or path provided -->
<Route handler={App}>
  <!-- path is automatically assigned to the name since it is omitted -->
  <Route name="about" handler={About}/>
  <Route name="users" handler={Users}>
    <!--
      note the dynamic segment in the path, and that it starts with `/`,
      which makes it "absolute", or rather, it doesn't inherit the path
      from the parent route
    -->
    <Route name="user" handler={User} path="/user/:id"/>
  </Route>
</Route>

Router.createTop-Level

Creates a new router. Useful to pass around your app to be able to call transitionTo and friends w/o being inside of a component.

Signature

Router.create(options)

Options

routes

location

scrollBehavior

onAbort

Used server-side to know when a route was redirected.

Methods

run(callback)

Runs the router, the same as Router.run.

Example

// the more common API is
Router.run(routes, Router.HistoryLocation, callback);

// which is just a shortcut for
var router = Router.create({
  routes: routes,
  location: Router.HistoryLocation
});

router.run(callback);

Router.runTop-Level

The main API into react router. It runs your routes, matching them against a location, and then calls back with the next state for you to render.

Signature

Router.run(routes, [location,] callback)

Arguments

routes

Your route config. See Route

location optional

Defaults to Router.HashLocation. If given a Location object, it will setup and listen for changes on it, if given a string path, the router will immediately match that path and callback.

Examples

// Defaults to `Router.HashLocation`
// callback is called whenever the hash changes
Router.run(routes, callback);

// HTML5 History
// callback is called when history events happen
Router.run(routes, Router.HistoryLocation, callback);

// Server rendering
// callback is called once, immediately.
Router.run(routes, '/some/path', callback);

callback(Root, state)

The callback receives two arguments:

  1. Root
  2. state

Root

A ReactComponent class with the current match all wrapped up inside it, ready for you to render.

state

An object containing the matched state.

state.path

The current URL path with query string.

state.action

The action that lead to the route change.

state.pathname

The current URL path without the query string.

state.params

The active params in the location match.

state.query

The active query in the location match.

state.routes

An array of the matched routes. Very useful for fetching data before rendering.

See also: Route.

Examples

Basic Usage:

Router.run(routes, function (Root) {
  // whenever the url changes, this callback is called again
  React.render(<Root/>, document.body);
});

Sample data fetching using state.routes. Check out the async-data example.

var resolveHash = require('when/keys').all;

var SampleHandler = React.createClass({
  statics: {
    // this is going to be called in the `run` callback
    fetchData: function (params) {
      return fetchStuff(params);
    }
  },
  // ...
});

Router.run(routes, Router.HistoryLocation, function (Root, state) {

  // create the promises hash
  var promises = state.routes.filter(function (route) {
    // gather up the handlers that have a static `fetchData` method
    return route.handler.fetchData;
  }).reduce(function (promises, route) {
    // reduce to a hash of `key:promise`
    promises[route.name] = route.handler.fetchData(state.params);
    return promises;
  }, {});

  resolveHash(promises).then(function (data) {
    // wait until we have data to render, the old screen stays up until
    // we render
    React.render(<Root data={data}/>, document.body);
  });
});

Server Rendering

something.serve(function (req, res) {
  Router.run(routes, req.path, function (Root, state) {
    // could fetch data like in the previous example
    fetchData(state.routes).then(function (data) {
      var html = React.renderToString(<Root data={data} />);
      res.send(html);
    });
  });
});

LinkComponents

The primary way to allow users to navigate around your application. Link will render a fully accesible anchor tag with the proper href.

A Link also knows when the route it links to is active and automatically applies its activeClassName and/or activeStyle when it is.

Props

to

The name of the route to link to, or a full URL.

params

An object of the names/values that correspond with dynamic segments in your route path.

query

An object of the names/values that will become the query parameters in the path.

Example

// given a route config like this
<Route name="user" path="/users/:userId"/>

// create a link with this
<Link to="user" params={{userId: "123"}}/>

// though, if your user properties match up to the dynamic segements:
<Link to="user" params={user}/>

query

The query string parameters as a JavaScript object.

activeClassName

The className a Link receives when its route is active. Defaults to active.

activeStyle

The styles to apply to the link element when its route is active.

onClick

A custom handler for the click event. Works just like a handler on an <a> tag - calling e.preventDefault() or returning false will prevent the transition from firing, while e.stopPropagation() will prevent the event from bubbling.

others

You can also pass props you'd like to be on the <a> such as a title, id, className, etc.

Example

Given a route like <Route name="user" path="/users/:userId"/>:

<Link to="user" params={{userId: user.id}} query={{foo: bar}}>{user.name}</Link>
<!-- becomes one of these depending on your router and if the route is
active -->
<a href="/users/123?foo=bar" class="active">Michael</a>
<a href="#/users/123?foo=bar">Michael</a>

<!-- or if you have the full url already, you can just pass that in -->
<Link to="/users/123?foo=bar">{user.name}</Link>

<!-- change the activeClassName -->
<Link activeClassName="current" to="user" params={{userId: user.id}}>{user.name}</Link>

<!-- change style when link is active -->
<Link style={{color: 'white'}} activeStyle={{color: 'red'}} to="user" params={{userId: user.id}} query={{foo: bar}}>{user.name}</Link>

RootComponents

A component created by React Router to be rendered at the top-level of your application.

Example

Router.run(routes, (Root) => {
  React.render(<Root/>, document.body);
});

Notes

Currently the router instance is the very same object as Root.

var MyRouter = Router.create({ routes });

MyRouter.run((Root) => {
  Root === MyRouter; // true
});

Currently this is simply an implementation detail, but we may eventually embrace this as public API.

Route HandlerComponents

A user-defined component given to a Route as the handler prop. The router will inject properties into your component when its rendered by RouteHandler, it also calls some lifecycle static hooks during transitions.

Injected Props

params

The dynamic segments of the url.

query

The query parameters of the url.

path

The full application url path.

Example

// given a route like this:
<Route path="/course/:courseId/students" handler={Students}/>

// and a url like this:
"/course/123/students?sort=name"

var Students = React.createClass({
  render () {
    this.props.params.courseId; // "123"
    this.props.query.sort; // "name"
    this.props.path; // "/course/123/students?sort=name"
    // ...
  }
});

Static Lifecycle Methods

You can define some static methods on your route handlers that will be called during route transitions.

willTransitionTo(transition, params, query, callback)

Called when a handler is about to render, giving you the opportunity to abort or redirect the transition. You can pause the transition while you do some asynchonous work and call callback(error) when you're done, or omit the callback in your argument list and it will be called for you.

See also: Transition

willTransitionFrom(transition, component, callback)

Called when an active route is being transitioned out giving you an opportunity to abort the transition. The component is the current component, you'll probably need it to check its state to decide if you want to allow the transition (like form fields).

See also: Transition

Note about callback argument

If you add callback to your arguments list, you must call it eventually, even if you redirect the transition.

Example

var Settings = React.createClass({
  statics: {
    willTransitionTo: function (transition, params, query, callback) {
      auth.isLoggedIn((isLoggedIn) => {
        transition.abort();
        callback();
      });
    },

    willTransitionFrom: function (transition, component) {
      if (component.formHasUnsavedData()) {
        if (!confirm('You have unsaved information,'+
                     'are you sure you want to leave this page?')) {
          transition.abort();
        }
      }
    }
  }

  //...
});

RouteHandlerComponents

Component that renders the active child route handler of a parent route handler component. Any time you have nested routes you need to render a RouteHandler to get the UI to nest.

We recognize its a bit confusing at first the difference between RouteHandler and a "Route Handler" supplied to Route. You define a "Route Handler" and you render it with RouteHandler inside your route hierarchy. A better name would be ActiveChildRouteHandler but we're guessing you don't want to type that.

Example

// given these routes
var routes = (
  <Route handler={App}>
    <Route name="about" handler={About}/>
    <Route name="home" handler={Home}/>
  </Route>
);

// `RouteHandler` will render either `About` or `Home`, depending on
// which one is matched in the url
var App = React.createClass({
  render () {
    return (
      <div>
        <h1>App</h1>
        <RouteHandler/>
      </div>
    );
  }
});

Custom LocationLocations

The router uses "location" objects to determine the current state of the application and update it when needed. In a browser environment, the location represents the URL in the browser's location bar. On the server, the location is the URL path that was used in the request.

You can also supply the router with your own location implementation. The following methods must be implemented:

Methods

addChangeListener(listener)

Adds a function to the location that should be called when it changes.

removeChangeListener(listener)

Stop calling the given function when the location changes.

push

Called when the router is transitioning from one path to another.

replace

Called when the router is replacing (not transitioning) one url with another.

pop

Called when the router attempts to go back one entry in the history.

getCurrentPath

Should return the current URL path, complete with query string (if applicable). This method should be ready to go immediately after setup.

toString

Should return a useful string for logging and debugging.

History

Additionally, location objects must:

  • Increment ReactRouter.History.length immediately after the URL changes
  • Decrement ReactRouter.History.length immediately before going back to the previous URL

HashLocationLocations

Uses the hash (#) portion of the URL.

For example, your urls will look like this: https://example.com/#/courses/123.

This is the default location used in Router.run because it will always work, though we recommend you configure your server and use HistoryLocation.

Query Params

Query params in the portion of the URL before the # are completely ignored with HashLocation because they are not part of the URL that HashLocation manages. Query parameters after the # will work as expected.

For example: http://example.com/?lang=es#/messages?sort=date, lang=es is invisible to a HashLocation router, but sort=date is recognized, and will be used as the query parameters.

HistoryLocationLocations

Uses the HTML5 history API to create real URLs. We recommend you use this location. It has better looking URLs and is required for picking up a server rendered app in the browser.

You must configure your server to use HistoryLocation

Configuring your server

When a visitor sends the url /assignments/123 or /settings to your app, they both must send your client application to the visitor.

Here's an example using express:

app.get('*', function (req, res) {
  res.render('index');
});

This will route all requests to the index template rendered by your server and then React Router will take over from there.

Fallback for browsers that don't support it

If you specify HistoryLocation, React Router will detect support and fall back to RefreshLocation if HistoryLocation is not supported.

Why don't you just fall back to HashLocation?

Because we'd end up with multiple urls for the same UI, and as users with different location support share urls they become non-deterministic for the router to switch back and forth.

Additionally, many HistoryLocation apps will want to take advantage of what the hash is actually intended for: linking to specific elements in the page. We don't want to break this valuable feature of the web.

RefreshLocationLocations

Causes the entire page to reload with a round-trip to the server for every transition. In other words, its not routing in the client anymore.

This location exists as a fallback for HistoryLocation in browsers that don't support HTML5 history (IE8).

StaticLocationLocations

Used for stateless environments, like servers, where the URL is only given once. If you provide a string for the location of a router, it will use StaticLocation, so we don't expect you to need to use this directly.

TestLocationLocations

Useful for testing your app. Check out the tests in the git repo to see how its used (more docs soon? PRs welcome after you figure it out!)

ImitateBrowserBehaviorScroll Behaviors

Imitates the browser's built-in scroll behavior after route transitions.

In a non-client rendered app, the browser attempts to restore the scroll position of the page, but when a client router takes over, this useful feature of the web is often ruined.

ImitateBrowserBehavior imitates the browser's behavior by restoring the position when the user clicks the back/forward buttons.

This is the default behavior of React Router. To opt-out at any level of your hierarchy simply add ignoreScrollBehavior to the Route.

// opt-out of the default behavior
<Route ignoreScrollBehavior={true}/>

ScrollToTopBehaviorScroll Behaviors

Simply scrolls the browser to the top of the page on every transition so that users aren't left at the bottom of a page after clicking a link.

Example

var AppRouter = Router.create({
  scrollBehavior: Router.ScrollToTopBehavior
  //...
});

NavigationMixins

A mixin for components that need to create URLs and/or initiate transitions to other routes.

Instance Methods

transitionTo(routeNameOrPath, [params[, query]])

Programmatically transition to a new route.

Examples

this.transitionTo('user', {id: 10}, {showAge: true});
this.transitionTo('about');
this.transitionTo('/users/10?showAge=true');
this.transitionTo('http://example.com/users/10?showAge=true');

replaceWith(routeNameOrPath, [params[, query]])

Programmatically replace current route with a new route. Does not add an entry into the browser history.

Examples

this.replaceWith('user', {id: 10}, {showAge: true});
this.replaceWith('about');
this.replaceWith('/users/10?showAge=true');

goBack()

Programmatically go back to the last route and remove the most recent entry from the browser history.

Example

this.goBack();

makePath(routeName, params, query)

Creates a URL path to a route.

makeHref(routeName, params, query)

Creates an href to a route. Use this along with State when you need to build components similar to Link.

Example

// given a route like this:
// <Route name="user" path="users/:userId"/>
this.makeHref('user', {userId: 123}); // "users/123"

Example

var Navigation = require('react-router').Navigation;

React.createClass({
  mixins: [Navigation],

  render: function() {
    return (
      <div onClick={() => this.transitionTo('foo')}>Go to foo</div>
      <div onClick={() => this.replaceWith('bar')}>Go to bar without creating a new history entry</div>
      <div onClick={() => this.goBack()}>Go back</div>
    );
  }
});

StateMixins

A mixin for components that need to know about the active params, query and routes. Any handler on a route with dynamic segments will want to use this.

Instance Methods

getPath()

Returns the current URL path, including query string.

getPathname()

Returns the current URL path without the query string.

getParams()

Returns a hash of the currently active URL params.

getQuery()

Returns a hash of the currently active query params.

isActive(routeName, params, query)

Returns true if a route, params, and query are active, false otherwise.

getRoutes()

Returns an array of the currently active routes, in nesting order.

Examples

Usually you'll just want access to params and query:

// route
<Route name="user" path="user/:name" handler={User} />

// handler
var User = React.createClass({
  mixins: [ Router.State ],

  render: function () {
    var name = this.getParams().name;
    return (
      <div>
        <h1>{name}</h1>
      </div>
    );
  }
});

Let's say you are using bootstrap and want to get active on those li tags for the Tabs:

var Link = require('react-router').Link;
var State = require('react-router').State;

var Tab = React.createClass({

  mixins: [ State ],

  render: function () {
    var isActive = this.isActive(this.props.to, this.props.params, this.props.query);
    var className = isActive ? 'active' : '';
    var link = (
      <Link {...this.props} />
    );
    return <li className={className}>{link}</li>;
  }

});

// use it just like <Link/>, and you'll get an anchor wrapped in an `li`
// with an automatic `active` class on both.
<Tab to="foo">Foo</Tab>

TransitionMisc

A Transition object is sent to the transition hooks of a RouteHandler as the first argument.

Methods

abort()

Aborts a transition.

redirect(to, params, query)

Redirect to another route.

retry()

Retries a transition. Typically you save off a transition you care to return to, finish the workflow, then retry. This does not create a new entry in the browser history.