This blog post is a walkthrough of adding ReactJS.NET to a
Kentico Xperience 12 MVC application to enable the development of complex UIs with React and MVC. If you’re wondering if this is a feasible approach to creating large Kentico web applications, I can tell you it is, as we’ve already done it on
https://trustmarkbenefits.com/.
Why Use React With Kentico Xperience 12
But, before I get into how I’d like to discuss the why. There have been a lot of improvements in the JavaScript space in the last decade, and we would obviously like to take advantage of them. JQuery was great for a time, and it still has its uses, but for larger complex applications, it’s nice to take advantage of other libraries like React. There are many JavaScript technologies to choose from, and the debate can get quite personal when deciding, but I’ll walk you through why I chose React before I wrote my first line of JSX.
- Popularity. At the time of writing this blog post, it is the most popular Front End Framework (https://2019.stateofjs.com/front-end-frameworks/).
- Speed. React is known for being extremely fast and responsive. React can scale to extremely large and complex UIs because it's very efficient about how and when it manipulates the DOM (House, 2019).
- Composable. You can easily nest components in child components and pass data down to child components (House, 2019).
- Pluggable. Unlike larger, more full-featured frameworks like Angular, React is easily pluggable into existing applications. Since it's just a view layer, it can be easily integrated into other technologies. Or, you can use React to create an entire application (House, 2019).
- Isomorphic Friendly. Components can be rendered on both the client and the server, which is good for SEO. React doesn't need the DOM in order to render. Isomorphic rendering can increase perceived loading performance, and it avoids repeating code on the client and the server (House, 2019).
- Simple to learn. React is a very focused library that makes it simple to learn. The API is small, and there aren't many moving parts and concepts to master (House, 2019).
- Battle Proven. Created by Facebook and used extensively on Facebook.com, one of the most popular websites in the world. Today Facebook.com uses over 50,000 react components (House, 2019).
- React uses "HTML" in JS. Unlike Angular, Ember, and Vue that use "JS" in HTML.
- Notice how you have to learn a proprietary domain-specific language to work with any of these:
- Angular: <div ng-repeat="user in users">
- Ember: {{#each user in users}}
- Vue: <li v-for="user in users">
- React puts "HTML" in JS with JSX, which isn't mind-blowing; it's just the polar opposite of the mindset that has been popular over the last few years. Instead of enhancing HTML to support simple logic, data binding, and looping semantics with React, you use JavaScript to define your markup. This has some clear advantages since javascript is a far more powerful technology than HTML. This means you can enjoy all the power of JavaScript when composing your JSX (House, 2019). You’re also getting more practice at writing pure JavaScript as an added bonus.
How to Use React With Kentico 12
Now for the how. To use React with a Kentico 12 MVC site, you can use ReactJS.NET. Here is a summary of this technology from the creators of ReactJS.NET:
ReactJS.NET makes it easier to use Facebook's
React and
JSX from C# and other .NET languages, focusing specifically on ASP.NET MVC (although it also works in other environments). It supports both ASP.NET 4 (with MVC 4 or 5), and ASP.NET Core MVC. It is cross-platform and can run on Linux via Mono or .NET Core. Take a look at
the tutorial to see how easy it is to get started with React and ReactJS.NET!
Now, it’s time for the demo. To complete the demo, I used the following tools:
First, let’s run the Kentico 12.0 Installer and select the Quick Installation option:
Next, open the DancingGoatMvc solution with Visual Studio usually installed here on a Windows PC:
C:\inetpub\wwwroot\Kentico12\DancingGoatMvc.sln.
After opening the project in Visual Studio, Right-click the DancingGoatMVC solution and select
add then
existing project. Double click the
CMSApp.csproj file found in the
Kentico12\CMS\ folder. Then, right-click the solution again and select
properties. Under
Common Properties -> Startup Project select
Multiple startup projects then set
CMSApp to
Start without debugging and
DancingGoat to
Start. Now run the project.
Two tabs should open in your browser. One for the CMSApp and one for the DancingGoat MVC site. Find the CMSApp tab and note that it will ask you for a license:
Follow the instructions for updating the license key (the username for logging into the admin side of a brand new Kentico site is
administrator; leave the password field blank).
Once you’ve added the license, you may need to add your localhost:port numbers as domain aliases. Navigate to
Sites, edit the
Dancing Goat MVC site and select
Domain aliases:
Then, select the
DancingGoatMvc site as the active site from the site drop-down list in the menu bar:
Now that the site is up and running, you’ll need to install ReactJS.NET. Stop the site in Visual Studio and right-click the
DancingGoat project and select
Manage NuGet Packages. Click the
Browse option in the top left and search for ReactJS.NET and install the
React.Web.Mvc4 package.
You will also need to install a JS engine (V8 and ChakraCore are recommended). See the
JSEngineSwitcher docs for more information. To use the
V8 JavaScript Engine add the following NuGet packages to the
DancingGoat project:
JavaScriptEngineSwitcher.V8
JavaScriptEngineSwitcher.V8.Native.win-x86
The
ReactConfig.cs file has been added to the
App_Start folder of the
DancingGoat project. We need to update this file to register a JavaScript Engine and setup the React Site Configuration. Copy the following code into
ReactConfig.cs:
using DancingGoat;
using JavaScriptEngineSwitcher.Core;
using JavaScriptEngineSwitcher.V8;
[assembly: WebActivatorEx.PreApplicationStartMethod( typeof( ReactConfig ), "Configure" )]
namespace DancingGoat
{
public static class ReactConfig
{
public static void Configure()
{
ReactSiteConfiguration.Configuration = new ReactSiteConfiguration()
.SetReuseJavaScriptEngines(true)
// We’ll be providing babel in our React app so ReactJS.Net shouldn’t load it
.SetLoadBabel(false)
// We’ll be providing React in our React app so ReactJS.Net shouldn’t load it
.SetLoadReact(false)
// These 3 JS files will be created by our React app
.AddScriptWithoutTransform("~/Content/dist/vendor.min.js")
.AddScriptWithoutTransform("~/Content/dist/master.min.js")
.AddScriptWithoutTransform("~/Content/dist/runtime-master.min.js");
JsEngineSwitcher.Current.DefaultEngineName = V8JsEngine.EngineName;
JsEngineSwitcher.Current.EngineFactories.AddV8();
}
}
}
Next, we’ll create a new React project using Facebook’s popular Create React App bootstraper. My IDE of choice for user interface development is Visual Studio Code (you can also use a PowerShell window or your preferred IDE of choice). Let's open VS Code, and from the file menu, open the root folder of the project.
Then, from the VS Code toolbar, select
Terminal, followed by
New Terminal, to open a PowerShell window within VS Code.
If this is your first time creating a React application, you may want to follow these instructions, which include the installation of node.js:
https://github.com/facebook/create-react-app#creating-an-app. Otherwise, continue to the next step.
For this example, I’ll be creating the React Application by running:
npx create-react-app dancing-goat-ui
Once the application has been successfully created, you can navigate to the UI directory from the terminal using
cd dancing-goat-ui and then run the command
npm start to open the application in your browser:
Our new React application is working great! However, we still need to connect it to the MVC application to utilize server-side rendering. Next, let's create our first component called
test within a new
components folder (
dancing-goat-ui/src/components/test.js) and add the following code:
import React from "react";
import PropTypes from "prop-types";
const test = ({ text }) => {
return (
<div>
<h1>
React Test Component Text: <b>{text}</b>
</h1>
</div>
);
};
test.propTypes = {
text: PropTypes.string.isRequired,
};
export default test;
Next, we’ll need to replace the contents of
dancing-goat-ui\src\index.js with the following JavaScript:
import React from "react";
import ReactDOM from "react-dom";
import ReactDOMServer from "react-dom/server";
import test from "./components/test";
// All JavaScript in here will be loaded server-side
// Expose components globally so ReactJS.NET can use them
global.React = React;
global.ReactDOM = ReactDOM;
global.ReactDOMServer = ReactDOMServer;
global.Test = test;
Now, we need a way to load our test React component from an MVC view in our DancingGoat project. To do that, I’ll add the following highlighted HTML and Razor syntax to the top of the home view:
DancingGoatMvc\Views\Home\Index.cshtml:
@model DancingGoat.Models.Home.IndexViewModel
@{
ViewBag.Title = ResHelper.GetString( "DancingGoatMvc.Home" );
}
@section styles
{
@Html.Kentico( ).PageBuilderStyles( )
}
@section scripts
{
@Html.Kentico( ).PageBuilderScripts( )
}
<div>
@Html.React( "Test", new { text = Model.HomeSections.FirstOrDefault()?.Heading })
</div>
@helper MoreButton( string text, string url )
...
You’ll notice that the first parameter is the name of the React Component. The second parameter is an object that contains some test data. I chose to use the
HomeSections.Heading model data that already exists in the home view because I don’t want to get caught up in discussing how to create fields in Kentico and passing them through controllers and view models in this blog post. I just want to show you how to pass data from Kentico to React. The first
HomeSection.Heading data that we’ll find is “
Our Story” which you can see is already being displayed by the home page in a different section:
Once our React component is rendering successfully, we should see
React Test Component Text: Our Story at the top of the home page.
Next, at the bottom of the
DancingGoatMvc\Views\Shared\_Layout.cshtml file, we need to add the 3 JavaScript output files from the React application:
- vendor.min.js
- master.min.js
- runtime-master.js
To generate these files, we need to build the React application by running
npm run build in the terminal. The build output files are located in the
dancing-goat-ui\build\static\js folder. If you’d like to learn more about these files, the Create React App team has written up a great explanation here:
https://create-react-app.dev/docs/production-build/. As you can see in the build files, the Create React App team has included cache-busting by default because the output files include hashes that are based on the content within those files. When the code changes, the hash changes, and the browser cache is busted.
This would be great if we weren’t using Server Side Rendering. We’ll need to create a workaround for this issue that involves renaming the output files using static filenames like vendor.min.js and master.min.js to allow us to include them in our MVC application. If we don’t change this behavior, we’ll need to include the new hashed files every time our JavaScript changes in our React project, and different hashes get generated. This doesn’t mean we can’t use cache-busting either. At BizStream, we perform cache busting with ReactJS.NET on the MVC side by adding our own hashing logic, but that’s a blog post for another day.
To fix this issue, I created a new folder in the DancingGoat MVC project here:
DancingGoatMvc\Content\dist\
I also added the following highlighted scripts to the scripts section of the
dancing-goat-ui\package.json file to build the React application along with renaming and copying the files to the
DancingGoatMvc\Content\dist\ folder so the MVC project can access them:
"scripts": {
"start": "react-scripts start",
"test": "react-scripts test",
"eject": "react-scripts eject",
"build": "react-scripts build && npm run build-master-dist && npm run build-vendor-dist && npm run build-runtime-dist",
"build-master-dist": "copy build\\static\\js\\main*.js ..\\DancingGoatMvc\\Content\\dist\\master.min.js",
"build-vendor-dist": "copy build\\static\\js\\2*.js ..\\DancingGoatMvc\\Content\\dist\\vendor.min.js",
"build-runtime-dist": "copy build\\static\\js\\runtime-main*.js ..\\DancingGoatMvc\\Content\\dist\\runtime-master.min.js"
},
You might not like this solution, but I wanted to avoid ejecting the webpack.config file. If you’d like to directly access the webpack.config to configure the build, you can do so by running npm eject, but it’s a one-way operation, which means you can’t undo it, and you’ll need to maintain the webpack.config yourself from then on.
Let’s run the production build again with the command:
npm run build
You should now be able to find the 3 JavaScript files here:
DancingGoatMvc\Content\dist\. Now that we’ve generated our JavaScript files we need to add the script tags to reference them in the HTML of the MVC project. Let's add the following highlighted script tags at the bottom of
DancingGoatMvc\Views\Shared\_Layout.cshtml to allow the use of React components in any view in our MVC Application:
@Scripts.Render( "~/bundles/jquery" )
@Scripts.Render( "~/bundles/jquery-unobtrusive-ajax" )
@Scripts.Render( "~/bundles/jquery-validation" )
@Scripts.Render( "~/Scripts/responsiveMenuDropdown.js" )
@Scripts.Render( "~/Scripts/mobileMenu.js" )
@RenderSection( "scripts", required: false )
@Html.Kentico( ).ActivityLoggingScript( )
<script src="~/Content/dist/vendor.min.js"></script>
<script src="~/Content/dist/master.min.js"></script>
<script src="~/Content/dist/runtime-master.min.js"></script>
@Html.ReactInitJavaScript( )
</body>
</html>
That’s it! Let’s run the MVC application and see if it’s working correctly:
The React component is rendered correctly by ReactJS.NET and displays our test data from Kentico!
I hope this information is helpful during your next web project. Let me know if there’s anything you think could be done better in the comments section. Happy coding!
References
House, C. (2019).
Building Applications with React and Flux. Retrieved from
https://app.pluralsight.com/library/courses/react-flux-building-applications