I had recently posted a blog about a SharePoint Framework (SPFx) application customizer I built for use with hub sites in Office 365. The problem I currently have with Hub navigation is that all of the links are static links. This means, that whoever creates the common navigation must be cognizant of what links end users have access to. With that in mind, I built a new navigation the replaces the out-of-the-box hub site navigation elements with a security trimmed listing of sites within a Hub.
For brevity, this isn’t an all inclusive tutorial. It’s just discussing the high level changes to the original implementation of the application customizer.
How it works
The new navigation uses a combination of the SharePoint Search API and the new Hub sites API. When a user lands on a site collection that belongs with in a hub, I grab the hub site information to find all of the sites that exist within the hub using the Search API. The benefit of this, is that I can security trim a listing of sites with in the navigation. That means I can have sites in a hub that a user may not have access to, yet include them as elements in the global hub site navigation.
What’s wrong with V1?
While this approach is great and I have had quite a bit of success building out security trimmed navigation, the default implementation lacks the ability to use the existing hub site navigation elements. This is why I have released v2 which is available on GitHub for download.
The new application customizer still implements the “Sites” listing node in the navigation.
Adding existing Hub navigation
Version 2 is almost identical to version 1 with the exception that I am now pulling in the static elements from the default hub navigation. To do this, I’ve made some modifications to the base ReactHubsiteNavbarApplicationCustomizer.ts file, to set the Navigation property equal to the navigation array that returns from the _api/web/hubsitedata endpoint.
this._currentHubSiteData = await searchService.getHubSiteData().then((hubData: IAssociatedSite) => {
if(hubData){
return searchService.getHubID(hubData).then((hub: IHubSiteData) => {
//add existing hub navigation
hub.Navigation = hubData.navigation;
return hub;
});
}
else{
return null;
}
});
Now that I have the elements as part of the _currentHubSiteData object, I just have to modify my HubNavBar.tsx component to accommodate loading the existing navigation nodes. One thing that isn’t working currently with the commandbar, is the ability to have a navigation element with children, in which the parent link is clickable.
You may notice the methods are almost identical. Rather than refactoring… I’ve separated them out because I have some future changes I’d like to make specifically to the rendering of the trimmed sites listing.
Ability to edit navigation
Now that we are showing the existing navigation elements and hiding the existing Hub navigation html…I needed a way to allow users to add and edit the original Hub navigation. There is an endpoint at _api/Navigation/SaveMenuState for saving changes to the menu, however it is undocumented by Microsoft so I will avoid using it for now. Instead, I am going to re-use the out-of-the-box Hub site navigation control to manage adding/editing elements.
To do this, I am checking if the user has ManageWeb permission, and then I will show an edit button which will show/hide the original Hub navigation.
//if user has manage web permissions, show edit button
const hasPermission:boolean = this.props.context.pageContext.web.permissions.hasPermission(SPPermission.manageWeb);
if(hasPermission){
commandBarItems.push({
key:"editButton",
name:"Edit",
itemType:ContextualMenuItemType.Header,
onClick:this._editOnClick,
className:"editButton",
href:"#"
});
}
Caveat: The out of the box permission for managing Hub navigation is the new “Edit” permission. Which means that users in the Member group have access to change the navigation. I think this is a bit too much permission, so I am restricting the permissions to “ManageWeb”.
The Result
The end result is a combination of security trimmed sites listing within the hub and the existing hub site navigation. User’s with ManageWeb permissions on the Hub site will be able to see the edit button to modify the existing navigation elements.
Notes
Because of the caching in the customizer, it may take 15 minutes for changes to appear!
GitHub – https://github.com/bcameron1231/SharePoint-Framework/releases/tag/v2.0
Code is in pre-release and subject to change (refactoring).
Hi Beau – this article and the past are very informative. I’ve started with v2 and tried adding this to our tenant, and it does not appear to be taking hold. I deployed to the CDN, updated my path, added the app – my colleague can still see two sites in our test site collection, where he should only see one. Is there one simple way to tell that your component has deployed successfully?
LikeLike
Hi Chris, I replied on the company website post. However, I’ll re-post here, please respond wherever is easiest for you. Original Reply:
Thank you for checking out the solution. I’ve been meaning to update the code and documentation for this, but I’ve been pretty busy! If you open up Dev Tools in your browser (F12), you should be able to figure out a) if the component is trying to load or not and b) if there is an error preventing it from loading.
V2 is a bit different than V1 because it replaces the HubNav (which I actually don’t love at this point). Can you see if there is an error showing up for you, if there is, let me know and I’ll put out a remedy. Also, what commands are you using to deploy the Customizer to your site?
I’d also like to note, this was more of a demonstration of the functionality, feel free to clone and change the code on the GitHub site to suit your needs! Looking forward to hearing from you.
LikeLike
Hi Beau – I dont know that I deployed the customizer, which might be my issue. I simply packaged the solution per the commands in the readme, deployed the app to the app catalog (checked that the CDN path was correct), and then looked to see if the menu was security trimmed. I checked my features (both site and site coll level) to see if anything was being shown there, but it doesnt appear that this uses feature deployment.
Are there commands I have to run once the the app is installed to the app catalog? Fairly new to SPFx, and I really appreciate the help.
LikeLike
Hi Beau, a quick update – it appears that everything was deployed correctly. I do not see anything in the Dev Tools (F12) that indicates the solution is running, however. Again, if I missed a step between installing to the app catalog and then having the solution running on my modern hub site, then that may be the issue.
LikeLike
Hi Chris,
Can you run the PowerShell in this gist for me using the PnP PowerShell Module? Just make sure the clientsidecomponent Id matches your solution. Let me know if it shows up after running this. https://gist.github.com/bcameron1231/6df207182d18e920a91701ddead505b5
LikeLike
Ok, that seems to have changed my nav – so is that supposed to happen automatically, or are those commands required each time?
LikeLike
Now that I have this working, just a couple more questions:
– The navigation appears to disappear for a second before the new one appears – is this expected?
– The navigation also appears to have different styling – again, expected?
– Finally, the “Sites” node – renaming this can be done in code, obviously, but is there a way we can do this without hardcoding it?
LikeLike
Hi Chris,
Sometimes it will appear/disappear due to the nature of the page load for client side scripting. The Navigation does have different styling unfortunately, I’ve been working on a V3 which hopefully fits the needs better for some people. The “Sites” node can be modified. In that PowerShell script I sent you, you’ll notice on line 11, it says “NavHeading”. You can specify whatever you want the header to be! 🙂
Also, I’d like to re-iterate, while I have published this code for use, I can’t always keep up with the demands of it, so if you wish to contribute or make modifications, please do. It was really meant as a means to show people “what you can do” with hub sites and SPFx.
Let me know if I can be of any further assistance.
Thanks,
Beau
LikeLike
No doubt – this is very helpful, and if I have anything I can contribute, I certainly will.
LikeLike
Last point of feedback, and how I’m planning to modify this is – simply add the “Sites” header to the existing nav instead of creating a brand new Nav. By modifying the existing nav, you dont deal with the flicker, and you utilize the existing styles.
I’m going to work on implementing this, and I’ll see where I get.
LikeLike
Hi !
I am very new to the whole sharepoint framework stuff.
I ran the powershell script from the gist more than one time and got a new navigation bar everytime and I do not manage to understand how to remove them again 😛
Another question, is it possible to NOT put the security trimmed sites in the submenu ? Just put them straight on the bar together with the static links.
Thanks in advance and thanks for the awesome work with this customizer!
LikeLike
Hi! You could definitely modify the code to not use a sub menu, and instead just list them across the top. But it’s likely in most organizations, there will be many many sites within a hub, and that wouldn’t scale well visually unfortunately.
LikeLike
Might there be a mechanism in place that would allow more than one submenu? I’ve got a couple different categorizations of sites to add to my hub but don’t want to put them all under a single header.
LikeLike
This could definitely be built in. As it’s an open source project, a developer should be able to extend this as need!
LikeLike
Hi Beau
This is a great article. I have a question. Would we have two sets of navigation, The out of the box HUB navigatoin and the new nevigation that you added using the Fabric command bar?
LikeLike
Hi Manoj, so this actually hides in the out of the box nav during normal loading (not really supported, but only method possible currently). When you edit the nav, it shows back up for editing. It’s controlled via CSS in the solution.
Audience Targeting navigation is on the roadmap from Microsoft for the end of the year. Keep your eyes peeled for that.
LikeLike