Ninjas Practicing Multidimensionality


    1.1.0 • Public • Published

    React Router Redux Middleware

    Middleware for React + Router + Redux with Server Side Rendering.

    Attention, this is an experimental project. It requires basic knowledge of involved frameworks.


    npm install react-router-redux-middleware --save-dev

    We assume that you should already have express, webpack and webpack-dev-server. You will need them.

    Server rendering basically takes your application, applies same Babel transformations as Webpack do, then renders it to a string. Because of that you will also need a babel-cli since it's the easiest way to run the server with Babel:

    npm install babel-cli --save-dev

    We assume that you either have .babelrc file or babel section in your package.json.

    Alter your package.json and add to scripts section:

      "scripts": {
        "start": "NODE_ENV=development babel-node ./index.js",
        "server": "NODE_ENV=production babel-node ./index.js"

    Now it's time to configure your router.js:

    import React from "react";
    import {Router, Route} from "react-router";
    import NotFound from './NotFound';
    function def(promise) {
        return promise.then(cmp => cmp.default);
    export default function(history) {
        return <Router history={history}>
            <Route path='/' getComponent={() => def(import('./App'))}/>
            <Route path='*' component={NotFound}/>

    And the way how you render your app, this hackery is especially required if you use async routes:

    import React from "react";
    import {render} from "react-dom";
    import {Provider} from "react-redux";
    import {browserHistory, match, Router} from "react-router";
    import createRouter from "./router";
    import createStore from "./reduxStore";
    const mountNode = document.getElementById('app'); // !!!!! PLEASE NOTE ID OF MOUNT NODE !!!!!
    const store = createStore(window.__PRELOADED_STATE__); // !!!!! PLEASE NOTE THE NAME OF VARIABLE !!!!!
    function renderRoutes(routes, store, mountNode) {
        match({history: browserHistory, routes}, (error, redirectLocation, renderProps) => {
                <Provider store={store}>
                    <Router {...renderProps} />
            ), mountNode);
    renderRoutes(createRouter(browserHistory), store, mountNode);

    Here is the sample index.html that should be a part of webpack build, e.g. emitted to you output path. It could be a real file or generated by HtmlWebpackPlugin, but it has to be known by Webpack.

    <!DOCTYPE html>
        <meta charset="utf-8">
    <div id="app"></div><!-- !!!!! MUST EXACTLY MATCH THE SERVER CONFIG !!!!! -->

    Now let's set up the server.js, you can add more customizations if needed:

    import path from "path";
    import Express from "express";
    import webpack from "webpack";
    import Server from "webpack-dev-server";
    import createRouter from "./src/router"; // same file as in client side
    import createStore from "./src/reduxStore"; // same file as in client side
    import config from "./webpack.config";
    import {createExpressMiddleware, createWebpackMiddleware, skipRequireExtensions} from "react-router-redux-middleware";
    skipRequireExtensions(); // this may be omitted but then you need to manually teach Node to ignore non-js files
    const port = process.env.PORT || 3000;
    const options = {
        createRouter: createRouter,
        createStore: ({req, res}) => (createStore({
            foo: // pre-populate something right here
        initialStateKey: '__PRELOADED_STATE__', // !!!!! MUST MATCH THE CLIENT
        template: ({template, html}) => (template.replace(
            // !!!!! MUST MATCH THE INDEX.HTML
            `<div id="app"></div>`,
            `<div id="app">${html}</div>`
        templatePath: path.join(config.output.path, 'index.html'),
        outputPath: config.output.path
    if (process.env.NODE_ENV !== 'production') {
        const compiler = webpack(config);
        const middleware = createWebpackMiddleware(compiler, config);
        config.devServer.setup = function(app) {
        new Server(compiler, config.devServer).listen(port, '', listen);
    } else {
        const app = Express();
        app.listen(port, listen);
    function listen(err) {
        if (err) throw err;
        console.log('Listening %s', port);




    npm i react-router-redux-middleware

    DownloadsWeekly Downloads






    Last publish


    • kirill.konshin