SPFx Extension – Adding custom header and footer to SharePoint Site by Application customizer

Traditionally with classic SharePoint experience, we used to customize master page to add custom header and footer for branding purpose. With modern site experience in SharePoint, we don’t have any master page concept. So you would not be able to customize master page to get branding. But to overcome this limitation Microsoft has introduced  a way to inject custom header and footer on all pages via SPFx extension. Below article is about experience to try first hand on experience to create SPFx extension with application customizer.

Pre-requisites – Make sure you have development environment for SPFx framework setup. If not follow this link.

Open NodeJS command prompt

Go to path or create your folder where you want to create your solution, run below command to generate solution structure.

yo @microsoft/sharepoint

It will take some time and finally you should see below screen

Open your code in any editor, I prefer VS code. If you are using so..

Type ‘code .’ in same folder and it will open visual studio code with project open to edit.

SPFx extensions cannot be tested against local work bench, you would need to test it against live SP online site. But Microsoft has provided a way to debug and test it against live site without going through deployment process(of app catalog).  

Open serve.json in config folder.

Replace pageUrl property from below serveconfigurations and customHeader with you modern page where you want to test.. You can use any URL with modern experience.

{
 "$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
 "port": 4321,
 "https": true,
 "serveConfigurations": {
   "default": {
     "pageUrl": "https://contoso.sharepoint.com/sites/mysc/SitePages/SFPxApplicationCustomizerExtension.aspx",
     "customActions": {
       "fc14316e-72db-4860-8283-458154eaef3e": {
         "location": "ClientSideExtension.ApplicationCustomizer",
         "properties": {
           "testMessage": "Test message"
         }
       }
     }
   },
   "customHeader": {
     "pageUrl": "https://contoso.sharepoint.com/sites/mysc/SitePages/SFPxApplicationCustomizerExtension.aspx",
     "customActions": {
       "fc14316e-72db-4860-8283-458154eaef3e": {
         "location": "ClientSideExtension.ApplicationCustomizer",
         "properties": {
           "testMessage": "Test message"
         }
       }
     }
   }
 }
}

Before changing anything  to default generated code, we will first make sure that with default project is getting deployed and working correctly based on configuration. This is my way to doing things, first make sure that basic things are working correctly to identify any environment etc issues and then go for customization.

To run the solution, first we need to install/trust certificate

Go back to node js command prompt and type

gulp trust-dev-cert

It will ask below popup, you have to trust certificate so select ‘yes’

Once finished you should see below screen

Now it is time to test extension on live site.

Type ‘gulp serve’ command

You should see below following thing happening in you command prompt.

Below link would open in browser

https://xxxxxxx.sharepoint.com/sites/mysc/SitePages/SFPxApplicationCustomizerExtension.aspx?debugManifestsFile=https%3A%2F%2Flocalhost%3A4321%2Ftemp%2Fmanifests.js&loadSPFX=true&customActions=%7B%22sss16e-sssf-ssss-8283-458154eaef3e%22%3A%7B%22location%22%3A%22ClientSideExtension.ApplicationCustomizer%22%2C%22properties%22%3A%7B%22testMessage%22%3A%22Test+message%22%7D%7D%7D

It will ask to load debug script, click Load debug scripts.

Once page is loaded, it will show alert. Default project created with  yeoman is about showing alert message (injecting javascript on page) 🙂

With this message we can say that our configuration and environment setup is correct and we can go ahead with our customization. What we will do here is add a custom header/html at top

Open CustomHeaderApplicationCustomizer.ts

On top you will find only BaseApplicationCustomizer in import statement from sp-application-base

Add PlaceholderContent,PlaceholderName,PlaceholderProvider to this.  

import {
 BaseApplicationCustomizer,
 PlaceholderContent, 
 PlaceholderName, 
 PlaceholderProvider 
} from '@microsoft/sp-application-base';

Go to onInit function and add below code.

public onInit(): Promise<void> {
   Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);

   let message: string = this.properties.testMessage;
   if (!message) {
     message = '(No properties were provided.)';
   }

   Dialog.alert(`Hello from ${strings.Title}:\n\n${message}`);

   let topPlaceholder: PlaceholderContent = this.context.placeholderProvider.tryCreateContent(PlaceholderName.Top); 
       if (topPlaceholder) { 
           topPlaceholder.domElement.innerHTML = '<div><div style="text-align:center" > This is to demo SPFx extension to customize app header. </div> </div>';

   return Promise.resolve();
 }

Save the file.  If you gulp serve is already running, it will recompile/reload automatically.

If not, run gulp serve command again.

Go again to browser, click on load debug script button to load page. Once page is loaded you will see custom html text added on top of site.

Now let us add footer also to our page, add below code onInit function

//CODE to add custom html at footer
          let bottomPlaceholder: PlaceholderContent = this.context.placeholderProvider.tryCreateContent(PlaceholderName.Bottom); 
          if (bottomPlaceholder) { 
            bottomPlaceholder.domElement.innerHTML = '<div style="background-color: red;"><div style="text-align:center;" > This is to demo SPFx extension to customize app footer. </div> </div>';

Save the file and reload the page. you would see below html added in footer

This concludes our article on how to add header and footer to Modern pages.

Side Note – While this solution works with modern pages and is alternative to master page, I think its major drawback is that if you need to edit header and footer, we would have to edit solution code again and then redeploy. So I have created a interface via SPFx webpart which will allow us to add/modify/delete header and footer on modern pages without going through change in code and redeployment. Another advantage of having this Webpart is that we can use same Solution with multiple site collection which would definitely need different header and footer. So this solution comes in handy.

P.S – to bundle app and deploying to SharePoint online use article at below link

Hope this helps…Happy Coding..!!!