Single Page App in SharePoint


  • Create a Single Page App using Node.JS
  • Enable live reloading using webpack configuration
  • Handle Routes to Single Page

Create project using uifabric framework.

npm init uifabric
Open webpack.serve.config and update web pack plugin to enable live reloading
const { webpackMerge, htmlOverlay, webpackServeConfig } = require('just-scripts');
webpackServeConfig.devServer = {
    https: true,
    port: 9000,
    allowedHosts: [
module.exports = webpackMerge(webpackServeConfig, htmlOverlay);

Activate publishing feature in site collection and at site level

Create a page called React.aspx with the following code
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<html >
<head runat="server">
  <SharePoint:SPShortcutIcon runat="server" IconUrl="/_layouts/15/images/favicon.ico?rev=47" />
  <form runat="server" >
        <SharePoint:FormDigest runat="server"/>
        <div id="app"></div>
        <script src="https://localhost:9000/dist/bundle.js"></script>

Upload this page to pages library. Go to 'site settings' and update navigation settings to 'Managed navigation' for global and current navigation. Open Term Store Management Tool. Create the term 'Coco' under site navigation. Under Navigation tab, select 'Term-Driven Page' with a Friendly URL

Under the Tab 'Term Driven Page', configure the friendly name and Target page settings

Screenshot coco friendlyurl

Click on 'Copy the term', this will create a new term with 'copy of coco', then rename it to 'Miguel'. As we are not updating the 'Term Driven Page', this will point to the same React.aspx.

Repeat this step for the following: Ernesto, Hector and Imelda

Add the following packages

 npm install react-router-dom @types/react-router-dom

Add the following Routes in the app, relative to the site URL

  • /teams/Demo/Coco
  • /teams/Demo/Miguel
  • /teams/Demo/Ernesto
  • /teams/Demo/Hector
  • /teams/Demo/Imelda
            <li key={"Coco"}>
              <Link to="/teams/Demo/Coco">Coco</Link>
            <li key={"Miguel"}>
              <Link to="/teams/Demo/Miguel">Miguel</Link>
            <li key={"Ernesto"}>
              <Link to="/teams/Demo/Ernesto">Ernesto</Link>
             <li key={"Hector"}>
              <Link to="/teams/Demo/Hector">Hector</Link>
              <li key={"Imelda"}>
              <Link to="/teams/Demo/Imelda">Imelda</Link>
        <Route path="/teams/Demo/Coco" component={Coco} />
        <Route path="/teams/Demo/Miguel" component={Miguel} />
        <Route path="/teams/Demo/Ernesto" component={Ernesto} />
        <Route path="/teams/Demo/Hector" component={Hector} />
        <Route path="/teams/Demo/Imelda" component={Imelda} />
npm start 

Create few lists, add data or content and navigate your routes. You will see the page with desired changes without a full page refresh/reload. Your 'Coco' app is now ready. Update the script reference in React.aspx, once the development is complete

Reasons behind this approach instead of using SPFx

  • SPFX support for On-Premise is limited

To achieve a similar approach using SPFx in SharePoint online


  • Performance
  • Can be useful to run the code under user context for web development
  • Supported in All versions of SharePoint Except in Modern Sites (I am unsure of the error I get while setting the managed navigation in modern Team sites and I cannot activate publishing features in Communication sites)
  • Streamlined development process for script injection


  • This doesn’t fall under Microsoft’s Recommended approach

You can use this approach for other developments. For example, if you are building a website using MVC using windows authentication, build the UI using modern frameworks like Angular/React. This approach is helpful to run and test the code under the user context


I used these names for the POC. Feel free to use names of your own.