Trimming the Suite Bar + Ribbon on Modern SharePoint Sites in Office 365

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.

12 Comments

  1. this is not supported…

    Important

    The SharePoint page HTML DOM is not an API. You should avoid taking any dependencies on the page DOM structure or CSS styles, which are subject to change and potentially break your solutions. SharePoint Framework provides a rich API to customize the SharePoint experience in reliable ways and is the only supported means to interact with the SharePoint page HTML DOM.

    in https://docs.microsoft.com/en-us/sharepoint/dev/spfx/enterprise-guidance

    • correct, I appreciate the comment. I agree the DOM is not an api and should be avoided if you want maintenance free environment. That is stated in the article. If you can’t live with ribbon and this is a blocker for you and you accept the risk then this article is for you. There are case where some organizations prefer to hide OOTB features to prevent uneducated users from clicking around too much or where they want a slightly more controlled environment.

      Also there’s nothing that can be done about the flash of the ribbon initially. Any custom code always loads after any Microsoft code. Saying that any customization will only take effect once your code is loaded. In this case the ribbon is seen for a few moments then removed. It’s not a bullet proof solution in that sense.

    • you have some trade offs here due to when app customizers load and caching. css vs js . Just remember all Microsoft code loads first, then it allows app customizers / webparts.

      the least amount of flicker is to hide the bar with CSS and then show it with JavaScript. the css will cache but there is always a flicker.

  2. Hello, I am new to Sharepoint and trying to apply your tutorial. I dit all the MS Sharepoint tutorials you advised (create an extension with top and bottom placeholders) but i am stuck with following errors when running ‘gulp serve’ :

    – ERROR TS2304: Cannot find name ‘IHeaderProps’
    – ERROR TS2552: Cannot find name ‘Header’. Did you mean ‘Headers’ ?

    I assume these need to be declared but how and where?

    For the React and the ReactDom I have added:
    import * as React from “react”;
    import * as ReactDom from “react-dom”;

    Do I need to understand that a file Header.tsx needs to be created ? If so, where to place this ?
    Thank you for your help.

      • Hi William,

        I’m not sure whether you will see this comment but I’m in similar position to yourself, could you perhaps expand on what you had to do to resolve these errors? Any help would be greatly appreciated.

        Thanks

        • Thanks for the feedback. The header is if you had a component you were creating in the application customizer. This was a snippet from my original POC. Tomorrow I’ll post a link to a sample github project with the complete solution.

      • Hi William,

        I don’t know whether you will see this but I am in the same situation as yourself. I was wondering if you could perhaps elaborate on how you were able to resolve these errors?

        Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.