Toggling SharePoint Modern Site Header Using SharePoint Framework (SPFx) Application Customizer

Why Site Header Toggler?

In SharePoint Modern Sites, the Suite Bar and the Site Header often occupy a lot of the viewport, and the actual content for a user to read is not immediately visible. Also as the Site Header is always positioned at the top, even though users scroll through the content, the viewport is much less. The Site Header occupies a significant amount in the viewport which really doesn't show any content of the intranet.
A Site Header Toggler would allow the users to hide the Site Header and gives more space to content which is easily readable. And users can always see the Site Header by toggling it again. Here is a sample of how it would work.

The Solution

This needs 2 buttons, one to close the header and one to open the header. And some CSS to hide/show the Site Header. The tricky part here is to define the CSS class to hide the Site Header section. The Site Header section on the modern pages doesn't have a CSS class name which we can override, and it is recommended to not change the DOM elements of a SharePoint Modern page. Here is a modern CSS construct which allows us to create a CSS definition based on the HTML element's custom attributes.
  1. // Sample HTML of the outer element of a Site Header  
  2. <div class="mainHeader-48" data-automationid="SiteHeader"> 
Css class definition using the custom attribute,
  1. div[data-automationid=SiteHeader]{  
  2. displaynone;  

The toggle buttons when clicked will add/remove a CSS class to the body element of the page, using which we can define CSS to show/hide the header.

Developing the SPFx Application Customizer

An Application Customizer of type of SPFx Extension adds some custom HTML in the top placeholder, where the HTML for showing toggling buttons can be added to every modern page on a SharePoint site.
  • Create a project with the name - 'js-application-header-toggler'
  • Open a command prompt in the new folder
  • Run 'yo @microsoft/sharepoint'
  • Provide the necessary values for the yeoman generator as shown below,

    • What is your solution name? js-application-header-toggler
    • Which baseline packages do you want to target for your component(s)? SharePoint Online only (latest)
    • Where do you want to place the files? Use the current folder
    • Do you want to allow the tenant admin the choice of being able to deploy the solution to all sites immediately without running any feature deployment or adding apps in sites? No
    • Will the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant? No
    • Which type of client-side component to create? Extension
    • Which type of client-side extension to create? Application Customizer
    • What is your Application Customizer name? HeaderToggler
    • What is your Application Customizer description? Adds a toggle button to the Site Header
Open the ' js-application-header-toggler/src/extensions/headerToggler/HeaderTogglerApplicationCustomizer.ts' file and make sure you have the following code.
  1. import { override } from '@microsoft/decorators';  
  2. import { Log } from '@microsoft/sp-core-library';  
  3. import {  
  4.   BaseApplicationCustomizer, ApplicationCustomizerContext,  
  5.   PlaceholderContent, PlaceholderName  
  6. } from '@microsoft/sp-application-base';  
  8. import * as strings from 'HeaderTogglerApplicationCustomizerStrings';  
  9. require('./HeaderTogglerStyles.css');  
  11. const LOG_SOURCE: string = 'HeaderTogglerApplicationCustomizer';  
  13. /** 
  14.  * If your command set uses the ClientSideComponentProperties JSON input, 
  15.  * it will be deserialized into the object. 
  16.  * You can define an interface to describe it. 
  17.  */  
  18. export interface IHeaderTogglerApplicationCustomizerProperties {  
  19.   // This is an example; replace with your own property  
  20.   testMessage: string;  
  21. }  
  23. /** A Custom Action which can be run during execution of a Client Side Application */  
  24. export default class HeaderTogglerApplicationCustomizer  
  25.   extends BaseApplicationCustomizer<IHeaderTogglerApplicationCustomizerProperties> {  
  27.   private topPlaceHolder: PlaceholderContent | undefined;  
  28.   private appContext: ApplicationCustomizerContext = null;  
  30.   @override  
  31.   public onInit(): Promise<void> {  
  32., `Initialized ${strings.Title}`);  
  33.     this.appContext = this.context;  
  35.     this.context.placeholderProvider.changedEvent.add(thisthis.renderPlaceholders);  
  37.     this.registerClickHandlers();  
  39.     return Promise.resolve();  
  40.   }  
  42.   private renderPlaceholders(){  
  43.     if (!this.topPlaceHolder) {  
  44.       this.topPlaceHolder = this.appContext.placeholderProvider.tryCreateContent(PlaceholderName.Top, { onDispose: this.onDispose });  
  45.     }  
  47.     if (this.topPlaceHolder.domElement) {  
  48.       let html: string = `<div class="toggleButton o365cs-base">  
  49.         <a class='toggleButtonClose' href='javascript:void(0);'>  
  50.           <span class="ms-Icon--ChevronUpMed _2e1Nb05SSaoOLYsNgNyvkr" role="presentation" style="display: inline-block;font-size: 20px;color: #fff;font-weight: bold;line-height: 30px;"></span>  
  51.         </a>  
  52.         <a class='toggleButtonOpen' href='javascript:void(0);'>  
  53.           <span class="ms-Icon--ChevronDownMed _2e1Nb05SSaoOLYsNgNyvkr" role="presentation" style="display: inline-block;font-size: 20px;color: #fff;font-weight: bold;line-height: 30px;"></span>  
  54.         </a>  
  55.       </div>`;  
  56.       this.topPlaceHolder.domElement.innerHTML = html;  
  57.     }  
  58.   }  
  60.   private registerClickHandlers(){  
  61.     let btnClose = document.getElementsByClassName("toggleButtonClose")[0];  
  62.     let btnOpen = document.getElementsByClassName("toggleButtonOpen")[0];  
  64.     btnClose.addEventListener('click', (e) => {  
  65.       document.body.classList.add("menuClosed");  
  66.     });  
  68.     btnOpen.addEventListener('click', (e) => {  
  69.       document.body.classList.remove("menuClosed");  
  70.     });  
  71.   }  

Add a CSS file named HeaderTogglerStyles.css in the folder js-application-header-toggler/src/extensions/headerToggler/. Copy the following content to this file.
  1. .toggleButton{  
  2.     background#666;  
  3.     positionabsolute;  
  4.     z-index9999;  
  5.     width30px;  
  6.     height30px;  
  7.     right: 0px;  
  8.     font-size0px;  
  9.     text-aligncenter;  
  10. }  
  12. a.toggleButtonOpen{  
  13.     display:none;  
  14. }  
  16. body.menuClosed a.toggleButtonOpen{  
  17.     display:inline-block !important;  
  18. }  
  19. body.menuClosed a.toggleButtonClose{  
  20.     display:none !important;  
  21. }  
  23. body.menuClosed div[data-automationid='SiteHeader']{  
  24.     display:none !important;  

  •  Update the SharePoint site URL in the 'js-application-header-toggler/config/serve.json' file
  •  In the command prompt run 'gulp serve'. This should open your SharePoint site with the SPFx extension from your local workbench
Follow the below steps to publish and deploy the SPFx solution,
  •  In the comment prompt run the following command,

    • npm run build
    • npm run bundle --ship
    • npm run package-solution --ship

  • Upload the generated sppkg file to your App Catalog
  • Add the app to your SharePoint modern site.


By providing a Site Header Toggler users can hide the header to create more reading space on the SharePoint modern pages and toggle the header anytime to make it visible again. It's a simple solution which would be very useful for creating a better viewport for the main content on the modern intranet pages.
This SPFx project is also available on GitHub.