How to marry ReactJS and Sitecore with Webpack – Part 2. Adding Redux

I’ve ended my previous post I’ve mentioned that I would add redux in a Sitecore-ReactJS mix. That is what I’m going to talk about in this post.

An original solution helps us to reuse ReactJS views in on server which actually could save us time in development and maintenance. It was more about a static content generation. While most of the sites I’m working with requiring more than that.

Take an e-commerce storefront, a travel site or utility customer portals, a customer would demand a lot of interactivity in all of them. Some would even be implemented as a SPA and use headless CMS approach. Last option isn’t the best case for Sitecore as we losing a lot of functionality built around presentation layer.

From my point of view, truth should be somewhere in between. In a hybrid approach, when we are able to generate pages from CMS and make them dynamic. And as we already using ReactJS views on a server adding stores, dispatchers and actions from Redux will help us to create these dynamics.


Redux is a predictable state container for JavaScript apps. It is inspired by Flux and could be  considered as it’s implementation (to some degree). Both frameworks concentrate logic related to model updated in a specific layer and don’t allow you to directly change model. Following diagram shows data flow in Redux applications:


If you are interested in other details you could watch videos from its creator, but at this point, I need to go back to the Sitecore solution.

As you remember in the previous post we created React views (represented on the diagram above by a green box with $ signs). So we need to create actions, reducers to mutate our model, store that would keep it and tie it all together.

Redux Components

I’ll start small, with simple components: counter and timer. The first component is Timer, it has one event ‘onTick’ that is generated by an internal timer. The event produces and action, that is processed by timer’s reducer and increment seconds counter in a model.

import React from 'react'
import { Grid, Row, Col } from 'react-bootstrap'
import * as actionCreators from '../../actions/timer';
const timer = React.createClass({
propTypes: {
data: React.PropTypes.shape({
title: React.PropTypes.string
getDefaultProps: function () {
return {
data: {
'title': 'This is timer'
getDispatch: function(){
return (typeof(this.props.dispatch) !== 'undefined')
? this.props.dispatch
: () => { };
tick: function() {
return this.getDispatch()(actionCreators.onTick())
componentDidMount: function() {
this.interval = setInterval(this.tick, 1000);
componentWillUnmount: function() {
render: function() {
const state = (typeof( !== 'undefined')
: { timer: 0 }; // so that is visible
return (
<Col xs={12} md={12} style={{fontSize: '20px'}}>
<h3><div dangerouslySetInnerHTML={{ __html: }} /> { state.timer }s</h3>
export default timer;
view raw timer.jsx hosted with ❤ by GitHub

Counter instead of the internal timer has 2 buttons, that increment and decrement another stored value (see code in the gist). But those two components are not alive yet.

Binding Redux Components

Next step is to connect those components to a store and make sure that React engine knows that it needs to update the component. In as SPA you most likely would have Provider component that wraps your app. It pushes store and dispatch() method to nested components via the context. Sitecore layout can contain React and MVC components and they can live in a pretty far parts of the page, it makes it difficult to use Provider.
Instead, I’m using subscribe() method of a store, and pushing render() method there for each component. Also, I’m explicitly passing store object and dispatcher function to each component. This is how store created:

import { createStore } from 'redux';
import reducer from '../reducers/common';
const store = (typeof(window) !== 'undefined')
? createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
: createStore(reducer);
const initialState = JSON.stringify(store.getState());
const reduxSc = {
initialState: initialState,
store: store,
dispatch: store.dispatch
export default reduxSc;
view raw store.js hosted with ❤ by GitHub

Rendering Redux Component on a Server

Redux has very little to do with a server side. The only thing that you need to consider on the server is a state, that is provided by a store. Nevertheless, I need to create two functions to render components to as string and to a static string (no react data attributes added).

import React from 'react'
import ReactDOM from 'react-dom'
import ReactDOMServer from 'react-dom/server'
import reduxSc from '../redux-sc';
import headerComp from './header';
import simpleContentComp from './simple-content';
import counterComp from './counter';
import timerComp from './timer';
const decorate = element => (
renderToDOM(props, node) {
const render = () => {
var el = React.createElement(element, { store:, dispatch: reduxSc.dispatch, data:, placeholders: props.placeholders });
ReactDOM.render(el, document.getElementById(node))
renderToString(props) {
var el = React.createElement(element, { store:, dispatch: reduxSc.dispatch, data:, placeholders: props.placeholders });
return ReactDOMServer.renderToString(el)
renderToStaticMarkup(props) {
var el = React.createElement(element, { store:, dispatch: reduxSc.dispatch, data:, placeholders: props.placeholders });
return ReactDOMServer.renderToStaticMarkup(el)
if(typeof(element) === 'undefined'
|| typeof(element.prototype.placeholders) === 'undefined') {
return '';
return JSON.stringify(element.prototype.placeholders)
// exports
export const header = decorate(headerComp);
export const simpleContent = decorate(simpleContentComp);
export const counter = decorate(counterComp);
export const timer = decorate(timerComp);
view raw components.js hosted with ❤ by GitHub

I’m using decorator here to wrap all components and add render functions. You might notice, that those functions duplicating functionality of By exporting those functions out of the webpack module, I’m able to fully control how I pass params to those components. Make sure that they know about a store, a dispatcher, and other goodness. On the other hand, I’m minimizing an amount of data that should be passed to this component from the server. It makes generated JS code a bit cleaner. As you see above, I do not need to generate render() methods and subscribe it to store- it is all done via the decorator.


I have one last thing that I need to mention before we move to back-end code. I get rid of expose module and generating global variables from a webpack module itself.

Server-side code in .NET. Stepping Aside from ReactJS.NET

The main idea behind ReactJS.NET is to provide a possibility to render JSX from a .NET server. The ability to use a compiled package was secondary. However, for my approach, it is a key and this means that I need underlying JS engine and JSPool more than the rest of the library.

ReactJS.NET is creating render() methods on the fly for required components, while but we exposed them already from a WebPack module as described above. In order to use them, we need to overwrite implementation of IReactEnvironment interface. It has a factory method for IReactComponent that we use. Finally, we need to register them all via IAssemblyRegistration.

Note: I’ve found a bug in IoC implementation of ReactJS.NET. It won’t allow you to rewrite registered implementation for an interface. As a workaround for that, I’ve recompiled original library without a default implementation.

I changed an implementation of a CreateComponent method to return ReduxComponents in ReduxEnvironmentclass.

using React;
using System.Text;
using System.Linq;
namespace Smagin.Alex.React
public class ReduxEnvironment : ReactEnvironment
public ReduxEnvironment(IJavaScriptEngineFactory engineFactory, IReactSiteConfiguration config, ICache cache,
IFileSystem fileSystem, IFileCacheHash fileCacheHash)
: base(engineFactory, config, cache, fileSystem, fileCacheHash)
public override IReactComponent CreateComponent<T>(string componentName, T props, string containerId = null,
bool clientOnly = false)
if (!clientOnly)
var component = new ReduxComponent(this, _config, componentName, containerId)
Props = props
return component;
public override string GetInitJavaScript(bool clientOnly = false)
var fullScript = new StringBuilder();
// Propagate any server-side console.log calls to corresponding client-side calls.
if (!clientOnly)
var consoleCalls = Execute<string>("console.getCalls()");
foreach (var component in _components.Reverse())
return fullScript.ToString();
view raw ReduxEnvironment.cs hosted with ❤ by GitHub

Besides that, I’ve updated a GetInitJavaScript method to revert an order of render methods generated in the bottom of the page. This is needed due to the specifics of Sitecore presentation rendering.
ReactJS.NET generating an init script at the end of a component processing. As a result, that nested component initialization scripts will appear first as they will finish rendering earlier. On the other hand, rendered HTML for a placeholder is passed as props to react component. So HTML that you need to bind you nested component to, might not exist if a parent component isn’t initialised. Reversing an initialization order solves the problem.

ReduxComponent class implements override to render methods RenderJavaScript and  RenderHtml. Both methods use functions exposed from WebPack instead of hardcoded templates.

using JavaScriptEngineSwitcher.Core;
using React;
using React.Exceptions;
namespace Smagin.Alex.React
public class ReduxComponent : ReactComponent
public ReduxComponent(IReactEnvironment environment, IReactSiteConfiguration configuration, string componentName,
string containerId) : base(environment, configuration, componentName, containerId)
public override string RenderHtml(bool renderContainerOnly = false, bool renderServerOnly = false)
if (!_configuration.UseServerSideRendering)
renderContainerOnly = true;
if (!renderContainerOnly)
var html = string.Empty;
if (!renderContainerOnly)
var reactRenderCommand = renderServerOnly
? $"{ComponentName}.renderToStaticMarkup({_serializedProps})"
: $"{ComponentName}.renderToString({_serializedProps})";
html = _environment.Execute<string>(reactRenderCommand);
string attributes = string.Format("id=\"{0}\"", ContainerId);
if (!string.IsNullOrEmpty(ContainerClass))
attributes += string.Format(" class=\"{0}\"", ContainerClass);
return string.Format(
"<{2} {0}>{1}</{2}>",
catch (JsRuntimeException ex)
throw new ReactServerRenderingException(string.Format(
"Error while rendering \"{0}\" to \"{2}\": {1}",
public override string RenderJavaScript()
return $"{ComponentName}.renderToDOM({_serializedProps}, '{ContainerId}')";
view raw ReduxComponent.cs hosted with ❤ by GitHub

That is it. We have no changes in controllers create or registration in Sitecore. It all could be done in the same way as described in the previous post.


You might have seen this GIF already in my twitter account as a spoiler to this post. Redux is connected to DEV tools in chrome and functioning as expected.


  • We exposing decorated components extended with rendering methods to Sitecore/.NET from WebPack .
  • Methods in the decorator providing functionality for generating DOM elements and HTML as a string. Methods are already connected to Redux store and dispatcher.
  • A default implementation of ReacJS environment in .Net is overridden with Redux implementation. Now it uses rendering methods from js module.


  • I need to try Dynamic Placeholders with this implementation.
  • Test performance of the JS engine in Sitecore. Maybe compare different implementations.
  • Caching should be revisited, as we generating JS initialization scripts in a request context. (I wrote about that a while ago)

Also the amount of code is growing as usual, so I would think how to create something on GitHub.

Follow me on twitter @true_shoorik. Would be glad to discuss ideas above in comments.

How to marry ReactJS and Sitecore with Webpack – Part 2. Adding Redux

One thought on “How to marry ReactJS and Sitecore with Webpack – Part 2. Adding Redux

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s