How to marry ReactJS and Sitecore with Webpack

There were a few posts on the internet on how to integrate front-end code into a Sitecore solution. It all started with a post from Alex Shyba. Back in February, he describes the general concept of an integration. Then Richard Seal created a module for Sitecore that allow you to use jsx renderings in Sitecore.

I was trying to solve a problem of an HTML handover between front-end and Sitecore developers for a while. Finally, I was able to play with ReactJS and Sitecore by myself and here is what I end up doing.

HTML Handover

Quite often we have an HTML created by some team and another team looking at this HTML creates ASP.MVC view. If a project is longer than 2 month, you will need to support both HTML and MVC views and it is a double effort.

If we able to use some HTML templates generated by the first team in Sitecore it would be ideal. If you take Angular 1.x, for example, you was able to create directives and pass data into them, which solves the problem to some degree. Yet your SEO wasn’t the best as search engines do not know how to process complex JS. Basically, there is no SEO in such case. This might be acceptable only for portals that need a login and won’t allow bots to see pages anyway but only in this case.

Angular 2.0 and  ReactJS are a bit different, they are not working with DOM directly. They creating lighter page component models in JavaScript and convert this structure into DOM or string if you working on a server. This allows us to prerender JS components on NodeJS server and speed up initial load of the application as well as improve SEO.

How NodeJS server side rendering could help us in a .NET application

Ability to render on a server is cool but how could it help in Sitecore, which is site? NodeJS is a web-server, which has Google’s V8 JavaScript engine in its heart. It adds to it various modules to work with the network, I/O, yadda, yadda. If this was done in NodeJS, you could that it could be done on other platforms including .NET.

ClearScript.V8 is one of such libraries for .NET. It wraps V8 and provides simple C# interface to interact with JS engine (pass a string with JS code into and Execute command).


ClearScript.V8 is actually used by ReactJS.NET to execute React methods and render JSX and other controls into a string. Like you would do in standard Node.JS app. the best thing is that all plumbing is done in this library and it is supported by Facebook itself. It allows you to render JSX files from server, which was described in details by Alex and Richard, and precompile jsx via webpack for e.g.

Angular 2.0 was released just a few weeks ago and might not have too many modules or similar commands (that is why I’m not going to talk about it any mode).


The idea is that you as a front-end developer uses NodeJS and creates your sandbox in it. In this sandbox, you might have sample pages, components, widgets, various tests for them and so on. Then you pack you app with webpack and make sure that you separate code. Your components should be in one package, vendor scripts, and scripts that provide governance in separate as well.

The components package should contain only components. It must not use any code that directly accessing DOM, otherwise, it is not isomorphic or universal and couldn’t be used on a server.

Then you reference the webpack package from Sitecore and use controls exposed via name in controller renderings. This which would give you full control in model preparation and error handling.

I disagree with a direct usage of JSX as it is not a full replacement for Razor views. It requires processing of JSX in .NET app and your Sitecore site need to know about many different view files. Reference of a pre-processed package allows you to define clear contract (set of components to be used) via one reference of a JS file.

On a Sitecore side, you could use standard controller renderings and it won’t even recognize that React is used somewhere.

NodeJS and Webpack config

The simplest way to configure client side solution is to use yeoman template, what I did with pretty much default configurations. Mian difference was creation os the second package for components (lines 13-16).

'use strict';
let path = require('path');
let webpack = require('webpack');
let baseConfig = require('./base');
let defaultSettings = require('./defaults');
// Add needed plugins here
let BowerWebpackPlugin = require('bower-webpack-plugin');
let config = Object.assign({}, baseConfig, {
entry: {
app: path.join(__dirname, '../src/index'),
components: path.join(__dirname, '../src/server.js')
output: {
path: path.join(__dirname, '/../dist/assets'),
filename: '[name].js',
publicPath: defaultSettings.publicPath
cache: false,
devtool: 'eval-source-map',
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new BowerWebpackPlugin({
searchResolveModulesDirectories: false
module: defaultSettings.getDefaultModules()
// Add needed loaders to the defaults here
test: /\.(js|jsx)$/,
loader: 'babel',
include: [].concat(
[ path.join(__dirname, '/../src') ]
module.exports = config;
view raw dist.js hosted with ❤ by GitHub

The package for components references a file that should gather all required references, in my case it is server.js. It uses node module expose to define a variable in a global scope. Using this variable you would be able to access your components from .NET.

var Components = require('expose?Components!./components/common');
view raw server.js hosted with ❤ by GitHub

A “Common” folder referenced in a server.js is a folder with components that I want to use on a server side.


ReactJS Components Implementation

You could create standard components as you would usually do for ReactJS. I’ve ended up using an old syntax (var xxx = React.createClass({…}) as there were some problems with the server using newer syntax. I think that I did something wrong with Babel configuration and my webpack packages were not automatically converted to ES5 standard (I saved it for later).

'use strict';
import React from 'react';
import { Grid, Row, Col } from 'react-bootstrap'
let yeomanImage = require('../../images/yeoman.png');
var SimpleContentComponent = React.createClass({
propTypes: {
data: React.PropTypes.shape({
image: React.PropTypes.string,
title: React.PropTypes.string,
text: React.PropTypes.string
}).isRequired ,
placeholders: React.PropTypes.shape({
leftColumn: React.PropTypes.string,
rightColumn: React.PropTypes.string
getDefaultProps: function() {
return {
data: {
image: '<img src="' + yeomanImage + '">',
title: 'SAMPLE: My First Sc.React Component',
text: 'SAMPLE: When designing interfaces, break down the common design elements (buttons, form fields, layout components, etc.) into reusable components with well-defined interfaces. <br/> That way, the next time you need to build some UI, you can write much less code. This means faster development time, fewer bugs, and fewer bytes down the wire.text'
placeholders: {
leftColumn: '',
rightColumn: ''
// this function would be called by ReactJS.NET to identify placeholders avaliable in a component.
getPlaceholders: function() {
return 'leftColumn|rightColumn';
render: function() {
return (
<Col xs={12} md={4}><div dangerouslySetInnerHTML={{ __html: }} /></Col>
<Col xs={12} md={8}>
<h1><div dangerouslySetInnerHTML={{ __html: }} /></h1>
<div className='rte'>
<div dangerouslySetInnerHTML={{ __html: }} />
<Col xs={12} md={6}><div dangerouslySetInnerHTML={{ __html: this.props.placeholders.leftColumn }} /></Col>
<Col xs={12} md={6}><div dangerouslySetInnerHTML={{ __html: this.props.placeholders.rightColumn }} /></Col>
module.exports = SimpleContentComponent;

There is one not standard function for a React component – getPlaceholders. Using this function I’ll let Sitecore know what placeholders exist in my component.

Sitecore Side of the Universe

First of all, you would need to install ReactJS.NET packages. Configure them by adding JS file generated by webpack via “AddScriptWithoutTransform()”. 2016-10-09_1010.png

Sitecore itself doesn’t need anything more than a React controller that inherits a standard SitecoreController and adds a few useful features. The first is a method that calls mvc.placeholder pipeline, which helps me to render a content of placeholders. The second is a method that returns ActionResult for React. It uses JS engine to get placeholders list defined in a ReactJS component, process its content and compose props for the component.

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Web.Mvc;
using Epam.Sc.EngX.CodeGeneration.Domain;
using Glass.Mapper.Sc;
using React;
using Sitecore.Data;
using Sitecore.Diagnostics;
using Sitecore.Mvc.Controllers;
using Sitecore.Mvc.Pipelines;
using Sitecore.Mvc.Pipelines.Response.RenderPlaceholder;
using Sitecore.Mvc.Presentation;
namespace Smagin.Common.Sc.Mvc.Controllers
public class SitecoreReactController : SitecoreController
private const string JsFunctionToGetPlaceholdersInfo = @"
if (typeof obj === 'undefined'
|| typeof obj.prototype.getPlaceholders !== 'function' ) {{
return [];
return obj.prototype.getPlaceholders();
protected readonly ISitecoreContext Context;
public SitecoreReactController() : this(new SitecoreContext())
public SitecoreReactController(ISitecoreContext context)
Context = context;
/// <summary>
/// Get current data source object and cast it to a specific model
/// </summary>
/// <typeparam name="T">Class, that implements IGlassBase interface</typeparam>
/// <returns>Retunrs and instance of T type</returns>
public T DataSource<T>() where T : class, IGlassBase
var datasourceId = RenderingContext.Current.Rendering.DataSource;
if (ID.IsID(datasourceId))
return Context.GetItem<T>(new Guid(datasourceId));
return Context.GetCurrentItem<T>();
/// <summary>
/// Generate a content of a placeholder into a string
/// </summary>
/// <param name="placeholderName">Name of a placeholder</param>
/// <param name="rendering">Rendering definition object</param>
/// <returns>Returns string with a rendered placeholder content</returns>
protected virtual string Placeholder(string placeholderName, Rendering rendering)
Assert.ArgumentNotNull(placeholderName, "placeholderName");
var stringWriter = new StringWriter();
new RenderPlaceholderArgs(placeholderName, stringWriter, rendering));
return stringWriter.ToString();
/// <summary>
/// Generate component ReactJS action results
/// </summary>
/// <param name="componentName">Name of a component exposed from a js package</param>
/// <param name="model">Data to be passed into a component</param>
/// <param name="renderContainerOnly">Render only container flag</param>
/// <param name="renderServerOnly">Use only server-side rendering code</param>
/// <returns>ActionResult object</returns>
public virtual ActionResult React(string componentName, object model, bool renderContainerOnly = false,
bool renderServerOnly = false)
return React(componentName, model, RenderingContext.Current.Rendering, renderContainerOnly, renderServerOnly);
/// <summary>
/// Generate component ReactJS action results
/// </summary>
/// <param name="componentName">Name of a component exposed from a js package</param>
/// <param name="model">Data to be passed into a component</param>
/// <param name="rendering">Rendering definition object</param>
/// <param name="renderContainerOnly">Render only container flag</param>
/// <param name="renderServerOnly">Use only server-side rendering code</param>
/// <returns>ActionResult object</returns>
public virtual ActionResult React(string componentName, object model, Rendering rendering,
bool renderContainerOnly = false, bool renderServerOnly = false)
// Get placeholders meta information from a React Component. List of placeholders separated by pipe
var placeholderKeys =
ReactEnvironment.Current.Execute<string>(string.Format(JsFunctionToGetPlaceholdersInfo, componentName)) ?? "";
// Create dynamic object to convert dictionary keys into object properties
dynamic placeholders = new ExpandoObject();
var placeholdersDictionary = (IDictionary<string, object>) placeholders;
foreach (var placeholderKey in placeholderKeys.Split(new[] {"|"}, StringSplitOptions.RemoveEmptyEntries))
placeholdersDictionary.Add(placeholderKey, Placeholder(placeholderKey, rendering));
// Create ReactJS component props object
var reactComponent = ReactEnvironment.Current.CreateComponent(componentName, new
data = model,
// Render ReactJS component
return Content(reactComponent.RenderHtml(renderContainerOnly, renderServerOnly));

When you combine this all together, as you might expect EE is fully functional.



  • Using webpack we could achieve a clean separation between HTML/CSS/JS and Sitecore/.NET.
  • Sitecore doesn’t need to know a location of views files, as he is not using MVC view renderings in this case.
  • Views itself could be pre-processed and outside of Sitecore.
  • Placeholders could be retrieved using JS call from ReactJS component itself, which simplifies configuration.


As you might expect this is a POC, but I still need to add Redux to the page. Also, make sure that it will work with components added dynamically to the page. Redux should not resend placeholders HTML and all localization data but only values needed for the logic.

Another question, which should be checked, is performance.

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

How to marry ReactJS and Sitecore with Webpack

5 thoughts on “How to marry ReactJS and Sitecore with Webpack

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