TL;DR Go here for the code + instructions: https://github.com/tom-daly/spfx-global-navigation
Modern version works with: Office 365 & SharePoint 2019 – IE 11, Chrome, Firefox.
Classic version works on any SharePoint [yes any] – IE 11, Chrome, Firefox
Introduction
Maintaining a consistent navigation across all site collections has always been a problem for SharePoint. Site collections do not share navigation. The story goes back to the beginning of SharePoint’s existence. In earlier versions 2007, 2010… it was recommended to break up sites into site collection to keep the content database sizes small. Microsoft had recommended maximums for best performance. Ultimately the content of SharePoint are table in a SQL databases and small databases meant faster, more manageable backups. Alternatively you could have all your sites in one site collection and then all the out of the box navigation options would be perfect.
Enter Modern… Each modern site is a site collection. This approach creates a flat hierarchy of sites. Each site collection having its own navigation, security, look and feel, content, components and more.
How can you create a consistent navigation across modern pages? Microsoft’s answer is to use Hub sites. “Hubbing” your sites will add a hub site navigation element to the top of the page.
Great! Hub sites to the rescue… What if you have some classic sites? Most organizations are currently in a hybrid mode of classic and modern pages. You can’t hub classic sites.
This blog will cover the solution that I built to add a list based navigation to modern pages using SPFx application customizer. But wait there’s more… It will also show you how you can use the same code base and repackage it to work on Classic SharePoint sites as well. Essentially creating the perfect cross site collection navigation solution that works on both classic and modern.
Solution Overview
The solution is broken down into a couple of parts. This blog is meant to explain the approach and the github repository contains an in depth guide to install and provision.
- Navigation List – PnP Powershell Template + Provisioning scripts
- SPFx application customizer – Global Navigation – React Component
Step 1 – Provision the Global Navigation List
I’m all about repeatable provisioning – as a developer I almost never create anything manually. In this solution I use Powershell PnP, mainly the provisioning template to provision the site columns, content types and list schema and connecting a lookup like with a cmdlet.
Using the list based approach, I can centrally host the list in the root site of the tenant where my users generally have read access. In the case that you have secured the root site from users, you could break permissions on the Global Nav List and grant read only access.
The list based approach has benefits that I like:
- It’s easy to talk to the list and using a simple rest query or PnP-JS as I do in this solution.
- Lists can be security trimmed so you can hide nodes from certain groups by breaking inheritance on those items. For those items they would have item level permissions.
- Lists are easy to work with for the end users, they don’t need lengthy instructions on how to manage the navigation
The entire list is easily deployable via the deploy.ps1 in the provisioning folder of the project. Check that out for an example of a template and the standard script I use to provision assets via Powershell PnP
Step 2 – SPFx Application Customizer
As of now the only way to install the solution is to build it. Clone or fork the repo and you’ll need to have a SPFx development environment in order to complete the build. Check out the github for the full instructions. Once you have the code, the build and deployment is the standard process for SPFx apps.
Future versions I might include a package that you download, let me know if that’s something you might want. Most people will want to at least customize the colors and best way is to get the code and do it yourself.
The SPFx Application Customizer lives inside the Header placeholder on any modern site that you add the app to. The code has been written such that it makes a call to the Global Nav List on the “/” root site of the tenant. You could change that location in the code and rebuild if you desired by modifying the GlobalNavProvider.tsx
Global Navigation
Once you’ve installed the list, add some nodes, deploy the app customizer, activate the app on a site you should get something like this below. The navigation can support as many levels as you want.
Classic Build
Yes it works on Classic SharePoint as well. By far the coolest part of this whole project. How can that be? For the complete explanation check out this article: SPFx Application Customizer that works on Classic SharePoint Sites.
Classic site deployment process is different. It’s not an app / app package. The solution creates a separate JavaScript file that is uploaded to your site and linked via a site script link.
To generate the latest JavaScript run the ‘build.cmd‘. That will generate both a new .sppkg for Modern sites and the .js file for Classic sites. After a successful build, the top-navigation.js file will be in the ‘classic-dist‘ folder.
If you want an automated deployment approach you would also want to run the deploy.ps1 file. The deploy script will upload the file and attach the JavaScript to your site collection. If deploying to multiple sites it’s a good ideal to centrally host this file in a CDN.
Once the file is attached via a script link, it’s live. Your site should look like this.
Conclusion
There you have it, a global navigation solution built for Modern sites using SPFx, Powershell PnP, PnP-JS, and Office UI Fabric that also works on Classic sites. One code base to maintain for both versions of SharePoint. This provides a flexible, consistent navigation for customers that have a mix of Classic & Modern sites.
Thank you for sharing this solution to a challenge I am facing building a SharePoint environment for my company in an on-premise SharePoint 2019 environment. I am trying to use host-named site collections because that appears to be the recommended way to do it and I am running into an issue with CORS blocking access to the global nav list on sharepoint.domain.local (my root site collection) from x.sharepoint.domain.local. The menu looks great on sharepoint.domain.local but doesn’t show up in any other site collections. Do you have any hints on how to overcome this issue?
javascript route it will always throw CORS, in the past we’ve synced the list data across the domains.
I get this error Field or property “HostProperties” does not exist
Add-PnPJavaScriptLink : Field or property “HostProperties” does not exist.
At C:\temp\spfx-global-navigation-master\sp2019\classic-dist\deploy.ps1:25 char:1
+ Add-PnPJavaScriptLink -Name “top-Navigation” -Url “$currentSiteServer …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (:) [Add-PnPJavaScriptLink], ServerException
+ FullyQualifiedErrorId : EXCEPTION,PnP.PowerShell.Commands.Branding.AddJavaScriptLink
Its probably related to the version of pnp powershell. this was written for pnp powershell v3, there is a new version out v4. Do you know which one you are using?
Hi Tom,
I dont get it built. In readme you write für SP 2019 NODEJS v8.x ist needed. But I dont get it build:
Error: Your dev environment is running NodeJS version v8.17.0 which does not meet the requirements for running this tool. This tool requires a version of NodeJS that matches >=10.13.0 =12.13.0 =14.15.0 <15.0.0
thank you for help in advance.
🙂
There are so many things that can go wrong that I would need to see your exact error.
Excellent Article. It worked great. One small addition could be.
Since it is primarily used for intranet purpose, would be great to have a column names “Secured or link type” with checkbox “yes/no” or dropdown secure or public in the Global Nav list – mean secure/public, secure mean “you need additional permissions” to click on the link.
Just like Home Icon, we can place “\E9A2” lock Fabric UI icon for the private/secure links.
Thanks for the comments – yes i have implemented that before for links that only work on VPN. I did not include that in here but it’s an easy enough addition.
Hi Tom, I just opened a issue on git repo. Just want make sure you saw that, putting the same here…
When I install the same app on another site collection with in the same webApp (other than root site), the navigation is missing, the dev console shows it is trying to load list from root site. But still nav is missing even though the logged in user has access to the list on root site.
I would like your help on:
1) A way to update the code to pick the Global Nav list from that particular site collection?
2) Or A way to make it work for all the site collections within that webApp, not just the root site collection?
Please ignore my earlier comment, it worked, mistake on my end.
Hi Tom,
Thanks for this solution. I have deployed it and everything is working fine. However, navigation only shows on the top site and not subsites. Am I missing something or should it be activate on all subsites as well ?
I will have a look this weekend. need to do some maintenance on my github projects.
Hi Tom,
Thanks for the solution. This is really great. I downloaded the solution but it is missing the provisioning folder. Not way to create the list. Can you provide some info on the list in case i need to create manually.
Sorry – just posted
Tried implementing this several times for O365 – always a correlation error.
I’ll check it out today/tomorrow and let you know. thanks for telling me which version you are using. I recently made some changes that worked on here but i’ll try it out on my new machine.
I just pulled down and I’m not getting a correlation ID issue however i am not able to see the global navigation anymore. I’m going to rebuild the o365 version of the project with the latest spfx version. You can use the sp2019 version. I just updated that and made sure it builds works for o365 as well.
I successfully built and deployed the sp2019 version to o365 today, using a fresh pull from git / on a clean machine.
tonight i’ll fix up the o365 version. thanks again for pointing this out. sorry you had so much trouble.
refreshed the entire project for the o365 version. brought it up to spfx v1.10.0 and replace office ui fabric icons with font awesome icons since office UI doesn’t seem to work anymore. It’s all functioning as expected. I need to double check the classic build to make sure that all works. It you O365 exclusively then this will work.
Hi Tom, love the idea of your solution. I’m targeting SharePoint 2019 instead of SPO. I’ve changed the .yo-rc json file and modified the environment and version parameters. Anything else I need to consider to make this a deployable solution for 2019? Thanks for the impressive work.
I had some feedback about the spfx version being higher than sp2019 supports and some feedback about deployment not working. I’ll be testing over the weekend and hopefully have some more guidance on sp2019 deployments.
I have posted an update in the github repo for a specific 2019 version built on spfx v1.4.1. Classic mode won’t build due to webpack issue which I am still working on.
Hi Tom,
I see you updated your solution for spfx 1.9.1. Is there an old version so that this could be built for SharePoint 2019 which is limited to spfx 1.4.1? Not seeing how I can pull a different version of the code.
Thanks for your time in advance!
yes i did recently update this. I will been checking sp2019 deployment again this weekend. I believe that I did not have a problem deploying but ill confirm. thanks for the feedback.
I have posted an update in the github repo for a specific 2019 version built on spfx v1.4.1. Classic mode won’t build due to webpack issue which I am still working on.
I tried to add the extension in my spfx and provisioned the global nav list.But the menu is not changing.
menu could be cached in session storage, either disable it and rebuild or open in new window after menu changes.
[…] Customizer, on a SharePoint 2013 site. Interested in that solution check out my other article Cross Site Collection Navigation for Modern & Classic SharePoint Sites. […]