Using React as a front end for Umbraco
Umbraco is great but have you ever thought about using a single page application framework on top of it?
I enjoy building responsive, reactive and immersive web front ends but using the MVC/Razor engine doesn't always achieve that.
Most interactions with a multi-page app are as simple as hyperlinks or html form posts. Certain effects can be achieved purely with CSS, but these are often more effort than they're worth.
React provides you with a robust, unopinionated framework for rendering content, handling user input and creating modular code with high reuseability. You can use it as much or as little as you want. Your entire app could be react, or as little as a button on a page - you use it how you want.
One of the reasons I enjoy using react is down to it's huge community and the packages they write for others:
Install "react-router" and suddenly you have the ability to have multiple pages in your application.
Need global state? Install "react-redux".
Want to animate your react components? Install "react-transition-group".
Almost anything your need or want to achieve in a web front end is probably already done for you and it's a couple of clicks away.
If you go a step further and pair React with webpack (and it's hot-module replacement feature) then you can literally see your application change before your eyes in real time as you make changes to the source code. None of this "save and reload the page" or "restart the application" shenanigans that you have to endure with MVC.
Umbraco generates urls for content, we're going to be using react-router which will hijack the routing for the application.
This means that content that we need from Umbraco, will require an API. Typically you can write a generic controller to get content based on URL or Id or what ever you want, but I generally find that creating actual controllers for content types & strongly typed models is a better experience. We wont be covering that in this blog post but, at the end of the day, just choose what is right for you.
Deeper Dive - Setting up Umbraco / Views / Build
At this point I'm going to assume you either have a fresh install of Umbraco or an existing install that doesn't do anything "funky".
Your React app can really live anywhere in your application but I've chose to put mine under /Content/Scripts/React.
I'm using webpack to build my app but we're not going to cover that here.
The output from my build goes to /Dist/client.bundle.js and /Dist/vendor.bundle.js.
These two files I've referenced at the bottom of my Master.cshtml file:
There should be one view that is returned by Umbraco from the Home node. this returns my index.cshtml which only specifies the Layout (Master.cshtml) and a div in which my react app will render:
And that's it - We're ready to start building.
This is the entry point in to your react app, the "root" if you will.
The responsibility of this module is to render the app in to our existing div and to orchestrate the top level parts of our application.
(We'll mostly be using functional components where we can but class components can be used if needed).
So what's going on here?
We're importing React and ReactDOM using ES6 import statements.
We're declaring a functional component "App" which will render a h1 containing the text "Hello".
and finally we're getting our app div from the document and using ReactDOM to render our app inside of that element.
Build your react app, reload the page and your spangly "Hello" should be rendered on the page!
Having a single file with your entire application isn't exactly what you want though so let's build out an actual "page".
He're we're declaring an exporting a new React functional component.
We're rendering a div with class "home-page" (react requires you to the the attribute "className" rather than class) and then a header and a bit of lorem.
Let's import that in to out app:
Now we're importing our home component from home.jsx. and then Rendering it inside of the app.
pretty cool but we want more that one page, right? Let's install React Router.
Install react-router-dom from npm or yarn.
Import BrowserRouter, Route and Switch from the library and we can add some pages:
So let's break this down:
BrowserRouter, Switch and Route are all known as "high order components". HoCs are components that don't provide any structural change to the DOM but encapsulate some type of logic.
BrowserRouter is the top level component for managing routes in the application.
Switch indicates that only one of the Routes should be show at a time.
And Route declares a url template and a matching component to that template.
So we can see here that the default route will return the Home component.
we can easily add to this by creating a new component, let's call it "about.jsx" and adding that to the routes:
To browse to this we can add a "Link" to the home page:
Now when the home page loads, we'll have a hyper link we can click on, which will take us to /about and render the about component.
One problem though, click "refresh". Page is not found.
this happens as we haven't told MVC that it can let React handle the routing.
So let's add some rules to our RouteConfig:
We're ignoring the Content path (as that will contain our assets etc), but the last rule is a catch all that will return out Home Index action (which renders our react app).
Then means that for any route, that isn't caught by a pre-configured handler, our React app will be rendered which will allow ReactRouter to render the correct component based on the url.
There's clearly a lot more to building a full site with authentication, menus and proper pages but for the purpose of this demonstration, this is how you use React (with routing) as the front end of your Umbraco CMS.