react-router-server codeclimate editorconfig eslint travis-ci npm

Server Side Rendering library for React Router v4.

React Router Server

Build Status Code Climate Dependency Status peerDependency Status devDependency Status npm downloads npm version Gitter

Server Side Rendering library for React Router v4. Allows to do code-splitting using webpack and to fetch data. Renders the page on the server side and resolves all issues with mounting on the client side.

Table Of Content

  1. Installation
  2. Example
  3. Usage
  4. API
  5. Webpack Bundle Support
  6. Contributing
  7. License


npm install react-router-server –save


A working example is provided in the example directory of this project. To try for yourself, you can clone this project and run npm start. This will provide a server accessible at http://localhost:3000.


Loading code splitted module

To load a module splitted by webpack use the importModule method and the Match component provided by this library.

import { Match, importModule } from 'react-router-server';

  render={matchProps => importModule('moduleName', './module', () => System.import("./module"))
    .then(module => {
      const Component = module.default;
      return <Component/>;

Loading props on the server side

To load props for your components to render on the server side, use the fetchState decorator.

  state => ({
    isLoaded: state.user ? true : false,
    user: state.user
  actions => ({
    done: actions.done
class MyComponent extends Component {
  componentWillMount() {
    if (!this.props.isLoaded) {
        .then(user => this.props.done({ user }));
  render() {

Server Side

You need to use the renderToString provided by this library:

import renderToString from 'react-router-server';
import { ServerRouter, createServerRenderContext } from 'react-router'

const context = createServerRenderContext();

      location={'/current/path/' /* provide the request url */}
).then(html => console.log(html)); // send html

An initial state and modules to preload will be passed through the context. You will need to pass these to your HTML template to preload the modules and pass the initialState to the client side.

import stats from './stats.json';

const initialState = context.getInitialState();
const modules = context.getModules(stats);

You will need to get the webpack stats to extract the modules from webpack. To do this, you can use the stats-webpack-plugin and add this line to your webpack config plugins.

  plugins: [
    new StatsPlugin('stats.json')

Client Side

Preload the modules in your HTML file if you are using code-splitting. Pass the initial state and modules to your app.

<link rel="preload" href="/path/to/module" as="script">

  window.__INITIAL_STATE__ = ...;
  window.__INITIAL_MODULES__ = ...;

Preload the modules in your JS before rendering the app.

import React from 'react';
import { BrowserRouter } from 'react-router';
import { render } from 'react-dom';
import { preloadModules, ServerStateProvider } from 'react-router-server';

preloadModules(__INITIAL_MODULES__).then(() => {
    <ServerStateProvider state={__INITIAL_STATE__}>
  ), document.getElementById('main'));



fetchState(mapStateToProps, mapActionsToProps)

mapStateToProps(state): function to map the state provided by the done action to props in your component;

mapActionsToProps(actions): function to map the actions to props in your component; Currently, only the done action exists and is used when you are finished fetching props.


importModule(name, path, systemImport)

name: Unique name of your module.

path: Path to your module relative to the current file. Same as the path in the systemImport param.

systemImport: A function returning a promise with your System.import("./path/to/your/module") call.


importModule(appSystemImport, moduleSystemImport)

systemImport: A function returning a promise with your System.import("./path/to/your/app.bundle") call.

moduleSystemImport: A function returning a promise with your System.import("./path/to/your/0.module.bundle") call. E.G. (path) => System.import('./' + path)


The Match component is the same as the react-router Match component but can be used for async render methods.



modules: array of modules passed by the server side to the client side for preloading.


Async version of ReactDOM.renderToString.

renderToString(element, context)

element: The element to render

context: The server context.


The ServerStateProvider component is used for providing the server state to the client side. Provided by the state prop.

Webpack Bundle Support

Server Side Rendering (SSR) is nice, but your app is probably complicated and uses Webpack loaders to load CSS or other types of files. Traditionally, this has always been complicated for SSR because those Webpack loaders are not supported by NodeJS.

To work around this limitation, you can import your Webpack bundle directly into your React Router Server application and do SSR on the bundle instead of importing the unbundled files.

To do this, you will need to create a bundle for the server app and a bundle for the client app, you will need the Webpack stats on both of them to cross reference the modules, as they won’t be the same for the server and the client.

React Router Server provides a importWebpackBundle method to import the bundle in your server.

Here’s a simple example of how this works:

import { ServerRouter, createServerRenderContext } from 'react-router';
import { renderToString, importWebpackBundle } from 'react-router-server';
import serverStats from './stats/server.json';
import clientStats from './stats/client.json';

  () => System.import('./app'), // path to your your server bundle
  (path) => System.import(`./${path}`) // callback for module imports inside your app
  then(({ default: App }) => {
    const context = createServerRenderContext();
          location={'/current/path/' /* provide the request url */}
      .then(html => {
        const result = context.getResult();
        const initialState = context.getInitialState();
        const modules = context.getModules(serverStats, clientStats); // you need to provide stats for the server bundle and the client bundle
        // send data to client, with the initial state and preloading the modules

To use System.import in your server script, take a look at the babel-plugin-system-import-transformer Babel plugin.


Everyone is welcome to contribute and add more components/documentation whilst following the contributing guidelines.


React Router Server is licensed under The MIT License (MIT).

Top Contributors

gabrielbull cmmartin yormi


-   1.1.1 zip tar
-   1.1.0 zip tar
-   1.0.5 zip tar
-   1.0.4 zip tar
-   1.0.3 zip tar
-   1.0.2 zip tar
-   1.0.1 zip tar
-   1.0.0 zip tar
-   0.5.0 zip tar
-   0.4.0 zip tar
-   0.3.0 zip tar
-   0.2.2 zip tar
-   0.2.1 zip tar
-   0.2.0 zip tar
-   0.1.4 zip tar
-   0.1.3 zip tar
-   0.1.2 zip tar
-   0.1.1 zip tar
-   0.1.0 zip tar