Goals
- 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
const { webpackMerge, htmlOverlay, webpackServeConfig } = require('just-scripts');
webpackServeConfig.devServer = {
https: true,
port: 9000,
allowedHosts: [
'.sharepoint.com'
]
}
module.exports = webpackMerge(webpackServeConfig, htmlOverlay);
Activate publishing feature in site collection and at site level
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<!DOCTYPE >
<html >
<head runat="server">
<SharePoint:SPShortcutIcon runat="server" IconUrl="/_layouts/15/images/favicon.ico?rev=47" />
</head>
<body>
<form runat="server" >
<SharePoint:FormDigest runat="server"/>
<div id="app"></div>
<script src="https://localhost:9000/dist/bundle.js"></script>
</form>
</body>
</html>
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
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
<Router>
<div>
<nav>
<ul>
<li key={"Coco"}>
<Link to="/teams/Demo/Coco">Coco</Link>
</li>
<li key={"Miguel"}>
<Link to="/teams/Demo/Miguel">Miguel</Link>
</li>
<li key={"Ernesto"}>
<Link to="/teams/Demo/Ernesto">Ernesto</Link>
</li>
<li key={"Hector"}>
<Link to="/teams/Demo/Hector">Hector</Link>
</li>
<li key={"Imelda"}>
<Link to="/teams/Demo/Imelda">Imelda</Link>
</li>
</ul>
</nav>
<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} />
</div>
</Router>
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
- Similar approach can be achieved in Modern Sites with hash routes Using single part app pages in SharePoint Online
Pros
- 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
Cons
- 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 ASP.net 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
Note
I used these names for the POC. Feel free to use names of your own.