Customizations – Inquisitive M365 https://thomasdaly.net Yet another SharePoint / Office 365 blog Fri, 06 Mar 2026 14:51:02 +0000 en-US hourly 1 116451836 Build a Site Directory with PnP Search Web Parts https://thomasdaly.net/2025/01/20/build-a-site-directory-with-pnp-search-web-parts/ https://thomasdaly.net/2025/01/20/build-a-site-directory-with-pnp-search-web-parts/#comments Tue, 21 Jan 2025 04:07:34 +0000 https://thomasdaly.net/?p=3324 This article will demonstrate how PnP Search Web Parts can be used to build a comprehensive Site Directory that not only enhances navigation but also improves the overall user experience by providing a centralized resource for accessing various sites within your organization.

Pre-Requisites

PnP Modern Search – Search Web Parts – v4

From your SharePoint site

Instructions

Create a new Page

Edit the Page

Add the PnP Search Results Web Part

Next click ‘Configure’

Next click ‘SharePoint Search’

Next click ‘Customize’ under ‘Layouts slots’

Add SiteUrl — mapped to SPSiteUrl, click ‘Save’

Edit the Query Template, using this as my base. It will show all ‘Sites’ and not the app catalog or my sites.

contentclass:STS_Site -"{TenantUrl}/sites/contenttypehub" -"{TenantUrl}/sites/appcatalog" -SiteTemplate:SPSPERS

** Thanks Kasper Larsen for the comment and suggestion to use the tokens for more resuability! **

Make sure to hit Apply to save the query.

Scroll down to the Paging Options

For our example we want to show as many sites as possible.

Set the number of items per page to 500

Click ‘Next’ to go to the second page of the property pane

Click ‘Custom’ Template and then {}

Replace this CSS

 /* Insert your CSS overrides here */
       .example-themePrimary a {
            color: {{@root.theme.palette.themePrimary}};
        }

        .site-logo {
            width: 35px;
            margin-right: 10px;
        }

        .icon {
            width: 20px;
            height: 16px;
        }

        ul.template--custom {
            list-style: none;
            padding-left: 5px;
	 columns: 4;
        }

        ul.template--custom li {
            display: flex;
            padding: 8px;
        }
        
        .site-link {
            line-height: 20px;
        }
        
        .site-link > a {
            display: flex;
            align-items: center;
        }
        
        .site-link, .site-link a, .site-link a:visited, .site-link a:hover, .site-link a:link {
            color: #000 !important;
            text-decoration: none;
        }

Next replace the item template

<template id="content">

 {{#> resultTypes item=item}}
                            {{!-- The block below will be used as default item template if no result types matched --}}
                            <li class="site-link">
                                <a href="{{slot item @root.slots.SiteUrl}}">
                                   <img class="site-logo" src="{{slot item @root.slots.SiteUrl}}/_api/siteiconmanager/getsitelogo?type='1'"/>
                                   <span class="site-name">{{slot item @root.slots.Title}}</span>
                                </a>
                            </li>
                        {{/resultTypes}}

                    </template>

Click ‘Save’

Click Republish

Your page should now look something like this

Conclusion

This is the first step toward making a Site Directory with all the sites you have access to. You could easily extend this to use a search box to filter these items down or change the KQL query to show only certain types of sites. You might also notice that the sites are not in order. In the next article I’ll walk you through the process of implementing the sort on the Site Name.

]]>
https://thomasdaly.net/2025/01/20/build-a-site-directory-with-pnp-search-web-parts/feed/ 5 3324
Adding Font Awesome to SPFx React project https://thomasdaly.net/2022/01/20/adding-font-awesome-to-spfx-react-project/ https://thomasdaly.net/2022/01/20/adding-font-awesome-to-spfx-react-project/#comments Thu, 20 Jan 2022 18:39:00 +0000 https://thomasdaly.net/?p=2688 Introduction

I love the FontAwesome library and use it on many projects. I was a huge fan of FontAwesome 4.0 and had a little struggle moving over to using 5.0 + 6.0 in my projects. I was use to the old way of including the link to the CSS files and using the class names. You can still do that if you wish but this article shows using the React component approach. It’s simple once you’ve done it a few times.

Install React Font Awesome

npm i –save @fortawesome/react-fontawesome

Install the Core Packages [required]

npm i --save @fortawesome/fontawesome-svg-core

Install the Icon Packages, use only the ones you need. If you only use solid icons then choose that. If you are not sure right now then you can include them all and remove them later.

npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons

Go Find a Fonthttps://fontawesome.com/icons

Keep in mind that you only have the free library so you can only use those unless you buy the pro license

If you pick an icon and it says ‘Start Using this Pro Icon’ then you need to choose something else or purchase a license

You can filter the free ones by clicking this on the left.

I’ve selected the fish icon, next you need to take note of the type ‘Solid’ or ‘Regular’

Now import the FontAwesomeIcon component and the icon you want from the correct package

This fish icon is in the Solid package.

If I wanted to use something from the regular package like this icon

This font is in ‘Regular’ package you would import it from that package instead

There is intellisense inside visual studio to help get the correct name of the icon

Now the result

If you wanted to use the brand icons you would follow the same approach. I believe that all the brands icons are free.

I love FontAwesome library of icons and use them in many projects. The PRO version unlocks so many more fonts and customizations that it’s worth buying if you plan to use them and want to support this project.

]]>
https://thomasdaly.net/2022/01/20/adding-font-awesome-to-spfx-react-project/feed/ 2 2688
Alerts Header – SPFx project https://thomasdaly.net/2021/10/10/alerts-header-spfx-project/ https://thomasdaly.net/2021/10/10/alerts-header-spfx-project/#comments Sun, 10 Oct 2021 21:24:00 +0000 https://thomasdaly.net/?p=2660

Introduction

This new project is a nice little feature that you can easily add to your SharePoint site to enable site messages or alerts. Having the ability to display site alerts is one of the top 10 most requested features to enhance SharePoint. This customization is built as an SPFx application customizer, with a little bit of UI hacking. This project can be used as-is or as a starting point for you to extend and create your own combinations of notifications, icons and colors.

  • Git Repo
  • Pre-Build SPPKG
  • Overview

    The Alerts Header solution contains an SPFx application customizer and a list schema for the alerts messages. The list will automatically be created for you when the app is added to your site. Currently the app displays messages from the site it’s in but could be easily modified to pull notifications from another site. Initially this was designed to be deployed the the entire intranet and activated on each site. Each site had the option to display ‘local’ alerts, alerts contained within the site and remote alerts, alerts contained at the root site collection “/”. The remote alert functionality has been commented out for simplicity in the Git Hub repo but could be reenabled with just a little effort.

    Implementation

    The List

    The solution installs an ‘Alerts’ list in your site. This list contains a number of required fields to properly display the alerts.

    Title – The first part of the text that is displayed

    Description – The second part of the text that is displayed. The description will fill the reminder of the space and truncate with ‘…’

    Alert Type – The icon that is displayed. Warning, Actionable or Info as show below from top to bottom.

    Link – The navigation url and the text that will be displayed

    Start Date / Time – The date and time that the alert will be displayed

    End Date / Time – The date and time that the alert will no longer be displayed

    Items will immediately start to show up once they are added to the list and hit the duration between the start and end date.

    The Web Part

    This view below shows the alerts application customizer with all three types of alerts and active.

    Icons – The icons used are from the Font Awesome 5.0 free library. You could easily update the code to change out the icons.

    Expand / Collapse – If the alert has a long description it will be truncated once it fills the available screen space. The up / down arrow will allow the user to expand and collapse the alert to read the full description.

    Dismiss / Close – The alert has and close icon at the far right to dismiss the alert. The alert will no longer show during that session. A new session will display the alert again. New Tabs are equivalent to new sessions.

    SharePoint UI Hack – I hinted earlier that I’ve included a bonus UI Hack for free, haha. Take a peek at the picture below. The normal location of an application customizer is at the very top of the page. I did not want the alerts to show up there so I opted to move them to the bottom of the header. This is a non supported customization according to Microsoft. I’m pointing this out for transparency.

    Responsive / Mobile Friendly – The web part was designed with the intention of working across all devices and screen sizes. The functionality is somewhat different on the mobile. Once the item is expanded it can only be closed. I’ve do it this way to intentionally close them out to regain the screen real estate back on the small devices.

    Customizations

    The web part comes with a few notification types. You can add more types directly to the list or to the list schema. After you add new Alert Types you would then need to do a few more updates

    IAlerts.types.ts – Add your new Alert Types to the enumeration

    AltertItem.tsx – Add new conditions for the new Alert Types and the icon you want to use

    AlertItem.module.scss – Copy / Paste an existing Alert Type combination and change the colors to meet your needs.

    Conclusion

    Site Alerts are one of the top 10 features requested from clients and customers to build. I’m happy to be able to post this feature to share even though it’s not 100% Microsoft compliant. The tiny UI hack positions this feature in the location where I felt it belongs. I hope and wish that Microsoft would give us more Zones in which we could target in the application customizers.

    ]]>
    https://thomasdaly.net/2021/10/10/alerts-header-spfx-project/feed/ 15 2660
    SharePoint – SPFX Back to Top https://thomasdaly.net/2021/08/14/sharepoint-spfx-back-to-top/ https://thomasdaly.net/2021/08/14/sharepoint-spfx-back-to-top/#comments Sat, 14 Aug 2021 04:35:03 +0000 https://thomasdaly.net/?p=2605 Introduction

    This post will demonstrate another SharePoint UI hack that is typically seen on many modern sites today. Back to top is a button that will position itself on the right hand bottom corner of the screen once you scroll a bit down. It’s very useful on long pages where your users might want to scroll up quickly and not get mouse scroll rash on their fingers in the process. This is another client request that I hear infrequently but I found this as something that the general population can implement and learn from.

    Before you continue, I must mention that SharePoint UI hacks are unsupported and frowned upon by Microsoft as we cannot rely on the UI [html, classes and DOM] to remain the same over time. With that said you are free to implement and learn more about SPFX and the current DOM given this example. When Microsoft implements a change this would potentially stop working and that is all. Post an issue on github and I would be happy to review and make a change.

    Overview

    I’m not going to go into the nitty gritty details of the code in this article, you can look at the code for that. This customization is based on an SPFX application customizer. This application customizer injects a button when the users scrolls past a certain point. The button would then jump the user back to the top of the scroll region.

    The scroll region might change at some point for SharePoint, rendering this customization ineffective.

    Implementation

    In the SPFX application customizer there is some code to detect the scroll event. There is also some code to detect the page navigation event as it’s somewhat tricky. When users navigate away from a page application customizers are not re-rendered. There is also some code to detect a navigation event and refresh the scroll area so that this SharePoint UI hack continues to work.

    The current scroll region is defined in the BackToTop.tsx. The current scroll region that is the target can be seen below.

    The customization is also theme aware and will respect the primary color of the theme.

    Installation

    As with many github solution you can always clone the repo and make any changes you desire to the solution, check out the REPO. Alternatively you can take the latest build and install it into your app catalog.

    Once you install the solution into your app catalog it will be available as an App on your site. It’s as simple as that.

    Summary

    I hope you enjoy this, yet another SharePoint UI Hack. It’s a great little enhancement if you have long content and want to scroll back up to the top of the page quickly. Feel free to use the github code to inspect how it’s implemented, make changes or enhancements or just implement it as the package is available for you. I’ll mention again that SharePoint UI hacks are not supported by Microsoft so don’t ask them for support. If you implement this you should always remove it before troubleshooting other issues. Generally it’s safe to apply as it won’t adjust or change anything permanently within your site, but take note that if there is a change with the SharePoint UI it could stop working as some point in the future. Please feel free to reach out or comment if your feedback or experience.

    ]]>
    https://thomasdaly.net/2021/08/14/sharepoint-spfx-back-to-top/feed/ 6 2605
    PnP PowerShell V4 Provisioning with Azure Functions V3 and Power Automate / Flow https://thomasdaly.net/2021/04/09/pnp-powershell-v4-provisioning-with-azure-functions-v3-and-power-automate/ https://thomasdaly.net/2021/04/09/pnp-powershell-v4-provisioning-with-azure-functions-v3-and-power-automate/#respond Fri, 09 Apr 2021 17:56:16 +0000 https://thomasdaly.net/?p=2357 Introduction

    Trying out the new way to Provision via PnP PowerShell V4 and Azure Functions V3 was a little challenging at first. There are some of the difference and issues that I encountered which I could not get to work correctly. I happen to be one of the early ones that need to do this because Azure had made a change to their interface which prevented using PnP PowerShell V3 and the Microsoft documentation was not updated. Since that time and now Microsoft has updated their online documentation with examples of the exact steps. I’ve decided to post the process I used to get everything working but I still suggest reading the official Microsoft article as well.

    Install PnP.PowerShell

    1. Open PowerShell 7 (if not installed, please install from here – https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows?view=powershell-7.1)
    2. Run the following cmdlet to install the PnP.PowerShell module

    Install-Module -Name "PnP.PowerShell" -RequiredVersion "1.5.0"

    Set up app-only access to your tenant

    1. Open PowerShell 7 and run the following cmdlets to register an Azure App

    Select the appropriate tenant name before running.

    Register-PnPAzureADApp -ApplicationName "PnPProvisioningDemo" -Tenant "<tenant-name>.onmicrosoft.com" -DeviceLogin -OutPath .

    Follow the instructions to complete the Azure AD App registration. You will need to open a browser and enter the url above and supply the code. You will also be asked to log in.

    This will now take 60 seconds to create the certificate in the out path that was specified in the above command

    • After the cmdlet is executed. It will create a PFX file. Keep this file saved, as we will have to upload it to Azure function.
    • Login to https://aad.portal.azure.com/
    • Click -> Azure Active Directory -> App Registration
    • Search for ‘PnPProvisioningDemo’ and the select the App Registration which got created. Copy the Application (client) ID from here.
    • Click API Permission
    • Click API Permissions, and Grant admin consent for {tenant}
    • In the small popup click Yes to approve this app those permissions.

    Create the Azure function

    • Type in ‘Function’ and select ‘Function App’
    • In the Project Details, click on Create New, for the Resource Group
    • Type in ‘PnPProvisioningDemo’ for the resource group name, click OK

    • Enter in a Function App name – this will need to be unique, Runtime Stack, Version and select a Region in which you want the resources inr its created, navigate to your new function App
    • From the dropdown menu, select host.json file and add the following entry and save it.
    • Click ‘Review + create’
    • Click ‘Create’

    After a few moments all of the assets will be created.

    • Click ‘Go To Resource’
    • Next click on ‘App Files’
    • I typically bump the timeout to 10 mins for the Azure Function from the default 5 minutes.
    • In the App Files > host.json, add this line. Make sure to use a ‘,’ on the previous line
    "functionTimeout": "00:10:00"
    • Click Save to lock in the changes
    • Click on the dropdown and select requirements.psd1
    • You can remove the ‘Az’ = ‘5.*’ as it won’t be used
    • Click Save to lock in the changes
    • Create a new Azure Function Functions > Add:
    • Create a new HTTP Trigger function, by selecting the options as shown below
    • Scroll down, name the function InvokePnPSiteTemplate
    • Set Authorization level, Anonymous
    • Click Save

    Upload the code for your Azure Function

    • Go to the Function App main screen and select Advanced Tools
    • Click “Go”, this will open Kudu
    • Select “PowerShell” from the Debug Console menu at the top.
    • Navigate to site\wwwroot\InvokePnPSiteTemplate

    This is where it gets complicated. Hold on to your hats.

    Extract the AzureFunCode.zip file provided as a sample.

    • Add your PnP template into the pnp-template.xml file
    • Update run.ps1
      • set $filePath to the correct drive [C or D] that you see in the azure portal
    • set $AzAppId to match your Azure App Id
      • set $certFileName to match your exported certificate
      • set $tenant to match your tenant prefix
    • Drag & drop the files to the site\wwwroot\InvokePnPSiteTemplate directory

    NOTE: If you want to use a different version of PnP PowerShell then you can generate the PnP.PowerShell files for upload from the command line. Use the folder that is exported to upload.

    Create a new folder and then execute the following commands

    Save-Module PnP.PowerShell . 
    1. After the code is updated. Navigate back to Function screen on Azure portal and click on ‘Get Function Url’ and copy the URL

    Create the Flow

    1. Go to the Power Automate site, sign in, and choose Create -> Automated Cloud Flow
    2. Click Skip at this screen
    1. Click ‘untitled’ and give the Flow a name, PnPProvisioningDemo
    1. Search for Request, and select Request – When a HTTP Request is received.
    1. Enter the following JSON as your request body:
    {
        "type": "object",
        "properties": {
            "webUrl": {
                "type": "string"
            },
            "parameters": {
                "type": "object",
                "properties": {
                    "event": {
                        "type": "string"
                    },
                    "product": {
                        "type": "string"
                    }
                }
            }
        }
    }
    • Select + New Step and choose Add an action.
    • In the search box type ‘http’ and click HTTP
    • Configure the properties as shown below.
    • You also need the Azure Function, HTTP endpoint. This is in the Azure Function, Overview screen, click Get Function Url
    • Copy this http endpoint to then paste into the flow
    • Choose Save Flow. This will generate the URL that you will copy in the next step.
    • Back in the Flow, Paste the URI in this box
    • Save the Flow
    • Once save is completed, click back on the first step and copy the Flow HTTP Post Url. Save this for later

    Create the Site Design

    In this section we are going to create a SharePoint Site Design, based on a Team Site template.

    1. Open SharePoint Online Management Shell and connect to your tenant using Connect-SPOService
    Connect-SPOService -Url https://[yourtenant]-admin.sharepoint.com
    • Update the URL property in the code below. Set the url property to the value you copied when you created the flow
    {
      "$schema": "schema.json",
      "actions": [
       {
          "verb": "triggerFlow",
          "url": "{UPDATE THE FLOW URL HERE}",
          "name": "Apply PnP Template",
          "parameters": {}
        }
      ],
      "bindata": {},
      "version": 1
    }
    
    • Select the JSON again and copy it, this will put it on your ‘clipboard
    • Open PowerShell and enter the following to copy the script into a variable and create the site script:
    $script = Get-Clipboard -Raw
    #before the next step verify you have data in $script by typing this
    $script
    #if that is empty try the copy and run the first line again.
    Add-SPOSiteScript -Title "Contoso Team Config" -Content $script
    Get-SPOSiteScript
    • You will see a list of one or more site scripts, including the site script you just created. Select the ID of the site script that you created and copy it to the clipboard.
    • Use the following command to create the site design:
    Add-SPOSiteDesign -Title "Contoso Team" -SiteScripts {Paste the ID of the Site Script here} -WebTemplate "64"

    Conclusion

    That completes all the necessary steps to get the basics up and running. Hope this was helpful walkthrough to make your first time getting started a little easier. The screens are constantly changing in Office 365 but the basics steps should remain the same. Leave a comment below if you get stuck or have a suggestion.

    ]]>
    https://thomasdaly.net/2021/04/09/pnp-powershell-v4-provisioning-with-azure-functions-v3-and-power-automate/feed/ 0 2357
    Remove Left Navigation on Modern Team Sites https://thomasdaly.net/2020/11/12/remove-left-navigation-on-modern-team-sites/ https://thomasdaly.net/2020/11/12/remove-left-navigation-on-modern-team-sites/#respond Thu, 12 Nov 2020 13:46:55 +0000 https://thomasdaly.net/?p=2188 I am frequently asked how do I removed the left navigation on the modern Team sites? Most people don’t know this but if you just remove all the items from the navigation it will go away on it’s own!

    The draw back is that it’s removed for the whole site. Maybe you just want it gone on one page. Well in that case you’ll have to use CSS to do that. For the one page approach I would add a Modern Script editor to the page.

    Immediately after removing the left navigation, depending on your screen size, you will notice that the screen does not go full width. This would also need to be fixed with injecting CSS either through the page or into the entire site via Application Customizer.

    not quite full screen

    Microsoft doesn’t recommend modifying their CSS but they almost give us no choice. For now I’ll leave you with the CSS that works (for now) to update these zones. You’ll need to use one of the two methods above to implement this on Modern pages.

    // Trimming Left Navigation
    #spLeftNav { 
     display: none;
    }
    
    // Full Screen CSS
    .CanvasComponent.LCS .CanvasZone {
     //there is a max width on this set to 1268px, we'll make it 100%
     max-width: 100%;
    }

    ]]>
    https://thomasdaly.net/2020/11/12/remove-left-navigation-on-modern-team-sites/feed/ 0 2188
    SPFx Side Navigation Project for Modern Sites https://thomasdaly.net/2020/06/09/spfx-side-navigation-project-for-modern-sites/ https://thomasdaly.net/2020/06/09/spfx-side-navigation-project-for-modern-sites/#comments Tue, 09 Jun 2020 17:53:09 +0000 https://thomasdaly.net/?p=1870 I started this project over a year and a half ago and at the time Modern SharePoint starts gaining some traction with organizations. I remember SPFx v1.4 was being released at the time and how far we’ve come from that today. I still find this project very interesting and useful today. It’s something different and on communication, sites can give you an option for navigation. Without further delay, I present to you the Side Navigation Project [inspired by the Office 365 Admin Tenant Navigation].

    Currently Supported [O365/SP2019 – IE11, Chrome, FF]

    The Side Navigation Project with full documentation can be found in my github repo https://github.com/tom-daly/spfx-side-navigation . That’s where you will find the installation guide and documentation. Please post any issues there – I’ll do my best to help if you are having trouble. This blog’s purpose to give a bit of background on the project and help showcase it.

    About the Project

    The Side Navigation purpose is to add a left navigation on Modern Communication site template that is unobtrusive to the main UI. It’s normally slim and compact but can be easily expanded to see what the icons nodes are.

    What makes it very cool is the fact that you can incorporate ANY svg icon. The only requirement is that it’s a single color icon – we use the SVG code in the list item and this allows us to recolor it along with the navigation nodes!

    Installation

    On installation and activation within your site it will create a list called Side Nav List. This list contains all the information needed to sustain the navigation. You can even create sub nodes b/c the list contains a lookup to itself. [this could be extended to infinite levels however the css does not support that currently / the code does]

    The Side Navigation is an SPFx application customizer that lives in the header area (if you are familiar with the placeholders) but it styles itself to the left of the page and pushed the main content over 50px. It fits nicely under the waffle or app launcher.

    Customization

    Colors

    You might be looking at it and say those colors aren’t going to fit site theme. We’ll you can download the solutions and QUICKLY change the colors of the site-menu.css file.

    Icons

    You can use any monochrome SVG you want as long as you can access the source [just open it in notepad]. SVG’s are freely available for a few dollars. My favorite sites for SVGs

    Navigation (advanced)

    Lastly the data source. Currently a list is deployed to the site on installation of the app. However you can make this global if desired. You can check out my global navigation project. You can modify the navigation provider to point to another source and when you deploy this out to various sites it will connect back to that source list.

    Check out the global navigation project and the GlobalNavProvider code – here … and you can see how i feel that provider a url. The current project also has a SideNavProvider which is set to look for the list in the current site but with a little develop know how you can change that !

    Why Navigation?

    If you haven’t seen my github repo’s before I have specialized in UI for all versions of SharePoint and I have many navigation projects going back to 2010/2013. If you like this project you’ll also like the Global Navigation Solution. It’s literally the same code! 😉 just styled a bit differently. The global navigation has some other enhancements as people have helped by submitting issues and requests. You can check that out here https://github.com/tom-daly/spfx-global-navigation

    ]]>
    https://thomasdaly.net/2020/06/09/spfx-side-navigation-project-for-modern-sites/feed/ 23 1870
    SPFx Application Customizer that works on Classic SharePoint Sites https://thomasdaly.net/2019/08/28/spfx-application-customizer-that-works-on-classic-sharepoint-sites/ https://thomasdaly.net/2019/08/28/spfx-application-customizer-that-works-on-classic-sharepoint-sites/#comments Wed, 28 Aug 2019 13:48:41 +0000 https://thomasdaly.net/?p=1685 Introduction

    Over a year ago I create a cross site collection navigation solution aka global navigation for Modern SharePoint sites using all the Microsoft goodies like SPFx, PowerShell PnP, PnP-JS & Office UI Fabric. At the same time, I had a very similar solution for Classic SharePoint sites for a different batch of clients. It was fairly typical for clients new to Office 365 go straight Modern and some of the more traditional SharePoint clients to stick with Classic sites.

    One day I was asked to put the global navigation on the Classic site and the Modern sites. It just didn’t feel right to me having 2 separate solutions. One being built with jQuery and JavaScript while the other built in SPFx using TypeScript, SCSS & React. The SPFx being the more current way of developing client-side solutions has spoiled me. I don’t dislike jQuery / JavaScript solutions… I just prefer the tooling SPFx offers for us SharePoint developers.

    New call-to-action

    How can an SPFx Application Customizer work on Classic sites?

    If you break it down, part of the secret sauce behind SPFx is that it’s simple a wrapper around plain old JavaScript that tells SharePoint where your file is and load it. SPFx provides other greater capabilities, like property pane which passes parameters to your JavaScript or React components.

    For Modern sites when you create a web part or app customizer there is a top level file. For example: in the global navigation projectSpfxGlobalNavigationApplicationCustomizer.ts. This file registers the Application Customizer and then loads the GlobalNav component into the Header placeholder [available on all Modern pages]. Everything inside the GlobalNav.tsx is React and nothing special.

    For Classic sites there is no built-in framework to inject components. This is something that must be addressed. In the global navigation project I create a component called ClassicMode.ts which is the top level file.

    Inside that file there is a reference to include @bable/polyfill. That helps supplement any browser shortcomings. On a Modern site there are already some polyfills so this would be unnecessary.

    Next there is a secondary style sheet which would be used to handle style differences between Classic & Modern sites. In the global navigation project, I am reference the Office UI Fabric library for icons. On a Modern site those are also already there so this would be unnecessary.

    Finally, on window load, the GlobalNav component is created into the element #DeltaTopNavigation. The DeltaTopNavgiation is the element where the default navigation is on a Classic SharePoint site.

    ** For this navigation scenario I am overwriting the default out of the box navigation. You can create a new DOM element and inject that anywhere and mount your React component into that new element. **

    That’s it in terms of the code. The code of the GlobalNav component is the same for both Modern & Classic sites. The Modern Application Customizer points to the same files that the ClassicMode component points to.

    Building an SPFx Application Customizer for Classic Sites

    Going back to what I said earlier, SPFx is simply a wrapper around plain old JavaScript. SPFx allows you to write in TypeScript/React/SCSS but browsers only understand HTML/CSS/JS, not those other languages. All of the SPFx code gets compiled into a single JavaScript file.

    You can’t just extract the JavaScript file from the .sppkg package and pop it into the Classic site.. that’s not going to work. The next step is to generate a new JavaScript that uses our new ClassicMode.ts file as an entry point. The key to this is Webpack.

    In the SPFx Application Customizer folder create a webpack.config.js. This will tell webpack to use our ClassicModer.ts as the entry point and produce a new file called top-navigation.js in a folder called classic-dist

    To execute webpack against this new file just run the following command:
    npx webpack --config webpack.config.js

    Note: This webpack file uses a few new dependencies that are NOT included with an SPFx project. You must include these new dependencies before you attempt to run webpack against this new config file.

    Attaching Classic Mode build to SharePoint Site

    The last thing we need to cover is how to hook up this file into your Classic SharePoint site. It’s straight forward and if you made it this far it should be a piece of cake.

    Step 1 – Upload the file. You can manually copy / paste the file into SharePoint. Alternatively you could host this file on a CDN if the plan is to use it on more than 1 site collection.

    Step 2 – Connect the JavaScript file to your site collection. You can’t do this through the UI unless you use a tool like SP-Editor for Chrome to attach a site script link

    Alternatively, check out how I upload it and activate it using PowerShell PnP with a deploy script.

    Classic Mode Deploy Script

    Conclusion

    That wraps up how to use your SPFx Application Customizer on a Classic SharePoint site. The most complicated part for me was building out the webpack.config.js file. It was a little tricky finding the right polyfills, getting the loading to work and testing across versions of SharePoint. I have even used this approach, for this project SPFx Global Navigation Application Customizer, on a SharePoint 2013 site. Interested in that solution check out my other article Cross Site Collection Navigation for Modern & Classic SharePoint Sites. Enjoy!

    ]]>
    https://thomasdaly.net/2019/08/28/spfx-application-customizer-that-works-on-classic-sharepoint-sites/feed/ 4 1685
    Cross Site Collection Navigation for Modern & Classic SharePoint Sites https://thomasdaly.net/2019/08/28/cross-site-collection-navigation-for-modern-classic-sharepoint-sites/ https://thomasdaly.net/2019/08/28/cross-site-collection-navigation-for-modern-classic-sharepoint-sites/#comments Wed, 28 Aug 2019 13:47:43 +0000 https://thomasdaly.net/?p=1672 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.

    1. Navigation List – PnP Powershell Template + Provisioning scripts
    2. 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:

    1. It’s easy to talk to the list and using a simple rest query or PnP-JS as I do in this solution.
    2. 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.
    3. 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.

    ]]>
    https://thomasdaly.net/2019/08/28/cross-site-collection-navigation-for-modern-classic-sharepoint-sites/feed/ 27 1672
    Trimming the Suite Bar + Ribbon on Modern SharePoint Sites in Office 365 https://thomasdaly.net/2018/05/14/trimming-the-suite-bar-ribbon-on-modern-sharepoint-sites-in-office-365/ https://thomasdaly.net/2018/05/14/trimming-the-suite-bar-ribbon-on-modern-sharepoint-sites-in-office-365/#comments Mon, 14 May 2018 08:00:43 +0000 https://thomasdaly.net/?p=1581 Update 2/26/2020 – due to the comments I’ve posted a github project that you can check out to help. https://github.com/tom-daly/spfx-trim-ribbon

    What I’m about to show you is a technique that you could use to trim the ribbon and suite bar off an Office 365 – SharePoint site. If you worked with any previous on-prem version we had the SPSecurityTrimmedControl where we could set permissions string. I first learned of this from Dr. Z’s famous post, “How To Hide Ribbon From Users Without Edit Page Privilege

     

    New call-to-actionIn comes new modern SharePoint sites and pages where we don’t have master pages to work with. Yet the desire of some clients to remove that top bar for users with minimal permissions still remains. So what can we do? I have 2 ways that I can show you how to accomplish this. Let’s start with the easy method and I’ll save the more complex for another post.

    Create an SPFx – Application Customizer 

    Create the basic hello world application customer. Click the link in the header to reference the Microsoft guidance. We are focused on the top placeholder for this example but any placeholder would work just fine. If you have an application customizer then skip this section

    Now that you have an application customizer with top placeholders you are ready for the good stuff.  For this we’ll use PnP JS library to check user permissions. This is consider the easier method because the PnP JS core library does all the heavy lifting. It allows you to easily make a call given a Permission level. Trust me, doing this yourself requires in depth knowledge about the High/Low security permissions, converting decimals to binary and mapping permissions to a bit on a binary string. If you are feeling adventurous you can read some more details on André Lage’s post “It is SharePoint Permission call FullMask or “NearFullMask” in CSOM?”

    Add PnP-JS to your project

    Follow the guidance here “Getting Started: Install & Use” with the NPM Install

    Now in your application customizer .ts file you need to import PnP

    import pnp from "sp-pnp-js";

    inside the onInit() you must initialize the pnp.setup before you call your content placeholders. If you don’t do this then pnp won’t be ready to use inside the content placeholders.

      @override
      public onInit(): Promise<void> {
        Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);
    
        return super.onInit().then(_ => {
          pnp.setup({
            spfxContext: this.context
          });
    
          this.context.placeholderProvider.changedEvent.add(
            this,
            this._renderPlaceHolders
          );
          this._renderPlaceHolders();
        });
    
      }

    This setups up PnP so it can do it’s work. My application customizer creates a sub component called Header and here is where I do my permission checking and trimming.

     private _renderPlaceHolders(): void {
        if (!this._topPlaceholder) {
          this._topPlaceholder = this.context.placeholderProvider.tryCreateContent(
            PlaceholderName.Top
          );
    
          if (this._topPlaceholder) {
            if (this._topPlaceholder.domElement) {
              const element: React.ReactElement<IHeaderProps> = React.createElement(Header, {});
              ReactDom.render(element, this._topPlaceholder.domElement);
            }
          }
        }
      }

    Insides Header.tsx I create a function that will trim the suite bar / ribbon. I am using pnp js to check for a particular security level and then hiding or showing. In my case below I’ve hidden the ribbon for everyone using CSS and then I unhide it here. You can use any of the PermissionKind enumeration listed here

    import pnp, { PermissionKind } from "sp-pnp-js";
      public componentDidMount(): void {
        this._trimSuiteBar();
      }
     
     private _trimSuiteBar(): void {
        pnp.sp.web.usingCaching()
          .currentUserHasPermissions(PermissionKind.EditListItems)
          .then(perms => {
            var suiteBar = document.getElementById("SuiteNavPlaceHolder");
            if (!suiteBar || !perms) return; //return if no suite bar OR perms not high enough
    
            suiteBar.setAttribute("style", "display: block !important");
          });
      }
    

    And there you have it. Suite Bar / Ribbon trimming on Modern Office 365 / SharePoint sites using an SPFx Application Customizer and PnP JS

    ** Disclaimer ** I have to tell you that this is simply for  information and demonstration purposes. Use at your own risk. It’s not recommended to trim the ribbon or suite bar as it provides functionality to users within the SharePoint site. This is obviously a hack to the product and I’m sure Microsoft would not like you to do this.

    ]]>
    https://thomasdaly.net/2018/05/14/trimming-the-suite-bar-ribbon-on-modern-sharepoint-sites-in-office-365/feed/ 12 1581