Navigation Bar In SPFx With Current User Greetings

Here we will see how to create a navigation bar using spfx extension. So let's see how we can achieve this.
 
md ext2
cd ext2
yo @ microsoft/sharepoint
 
What is your solution name?: ext2
 
Which type of client-side como you want to target for your component(s)? SharePoint Online only (latest)
 
Component to create?: Extension
 
What is your Application Customizer name? ext2
 
What is your Application Customizer description? ext description
 
After the scaffolding run the below command to install the office fabric ui:
 
npm install @microsoft/sp-office-ui-fabric-core
 
Then code.
 
Create a new file named ./src/extensions/ext2/AppCustomizer.module.scss.
 
Update AppCustomizer.module.scss as follows:
  1. @import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';.app {  
  2.     .top {  
  3.         height: 60 px;  
  4.         text - align: center;  
  5.         line - height: 2.5;  
  6.         font - weight: bold;  
  7.         display: flex;  
  8.         align - items: center;  
  9.         justify - content: center;  
  10.         background - color: $ms - color - themePrimary;  
  11.         color: $ms - color - white;  
  12.     }.bottom {  
  13.         height: 40 px;  
  14.         text - align: center;  
  15.         line - height: 2.5;  
  16.         font - weight: bold;  
  17.         display: flex;  
  18.         align - items: center;  
  19.         justify - content: center;  
  20.         background - color: $ms - color - themePrimary;  
  21.         color: $ms - color - white;  
  22.     }  
  23. }.topnav {  
  24.     overflow: hidden;  
  25.     background - color: black;  
  26. }.topnav a {  
  27.     float: left;  
  28.     color: #f2f2f2;  
  29.     text - align: center;  
  30.     padding: 14 px 16 px;  
  31.     text - decoration: none;  
  32.     font - size: 17 px;  
  33. }.topnav a: hover {  
  34.         background - color: #ddd;  
  35.         color: black;  
  36.     }.topnav a.active {  
  37.         background - color: #4CAF50;  
  38. color: white;  
  39. }  
In the Ext2ApplicationCustomizer.ts
  1. import {  
  2.     override  
  3. } from '@microsoft/decorators';  
  4. import {  
  5.     Log  
  6. } from '@microsoft/sp-core-library';  
  7. import {  
  8.     BaseApplicationCustomizer,  
  9.     PlaceholderContent,  
  10.     PlaceholderName  
  11. } from '@microsoft/sp-application-base';  
  12. import {  
  13.     Dialog  
  14. } from '@microsoft/sp-dialog';  
  15. import * as strings from 'Ext2ApplicationCustomizerStrings';  
  16. import styles from './AppCustomizer.module.scss';  
  17. import {  
  18.     escape  
  19. } from '@microsoft/sp-lodash-subset';  
  20. const LOG_SOURCE: string = 'Ext2ApplicationCustomizer';  
  21. export interface IExt2ApplicationCustomizerProperties {  
  22.     Top: string;  
  23.     Bottom: string;  
  24. }  
  25. /** A Custom Action which can be run during execution of a Client Side Application */  
  26. export default class Ext2ApplicationCustomizer  
  27. extends BaseApplicationCustomizer < IExt2ApplicationCustomizerProperties > {  
  28.     private _bottomPlaceholder: PlaceholderContent | undefined;  
  29.     @override  
  30.     public onInit(): Promise < void > {  
  31.         this.context.placeholderProvider.changedEvent.add(thisthis._renderPlaceHolders);  
  32.         return Promise.resolve();  
  33.     }  
  34.     private _renderPlaceHolders(): void {  
  35.         const topPlaceholder = this.context.placeholderProvider.tryCreateContent(PlaceholderName.Top, {  
  36.             onDispose: this.onDispose  
  37.         });  
  38.         if (!topPlaceholder) {  
  39.             console.error("The expected placeholder (Top) was not found.");  
  40.             return;  
  41.         }  
  42.         if (topPlaceholder.domElement) {  
  43.             topPlaceholder.domElement.innerHTML = `  
  44.   
  45.         <div class = "${styles.topnav}">  
  46.             <a class = "${styles.active}" href = "https://dronzer.sharepoint.com/sites/Barcelona/SitePages/Home.aspx">Home</a>  
  47.             <a href = "https://dronzer.sharepoint.com/sites/Liverpool">News</a>  
  48.             <a href = "https://dronzer.sharepoint.com/sites/chelsea">About us</a>  
  49.             <a href = "https://dronzer.sharepoint.com/sites/mancity">Find Mentor</a>  
  50.         </div>  
  51.         <span class = "${styles.top}">Hello! ${escape(this.context.pageContext.user.displayName)}</span>  
  52. `;  
  53. }  
  54.         // Handling the bottom placeholder  
  55.         if (!this._bottomPlaceholder) {  
  56.             this._bottomPlaceholder = this.context.placeholderProvider.tryCreateContent(PlaceholderName.Bottom, {  
  57.                 onDispose: this._onDispose  
  58.             });  
  59.             // The extension should not assume that the expected placeholder is available.  
  60.             if (!this._bottomPlaceholder) {  
  61.                 console.error("The expected placeholder (Bottom) was not found.");  
  62.                 return;  
  63.             }  
  64.             if (this.properties) {  
  65.                 let bottomString: string = this.properties.Bottom;  
  66.                 if (!bottomString) {  
  67.                     bottomString = "(Bottom property was not defined.)";  
  68.                 }  
  69.                 if (this._bottomPlaceholder.domElement) {  
  70.                     this._bottomPlaceholder.domElement.innerHTML = `  
  71.         <div class="${styles.app}">  
  72.             <div class="${styles.bottom}">  
  73.                 <i aria-hidden="true"></i> ${escape(  
  74. bottomString  
  75. )}  
  76.   
  77.             </div>  
  78.         </div>`  
  79.                 }  
  80.             }  
  81.         }  
  82.     }  
  83.     private _onDispose(): void {  
  84.         console.log('[HelloWorldApplicationCustomizer._onDispose] Disposed custom top and bottom placeholders.');  
  85.     }  
  86. }  
Update the serve.json file as
  1. {  
  2.     "$schema""https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",  
  3.     "port": 4321,  
  4.     "https"true,  
  5.     "serveConfigurations": {  
  6.         "default": {  
  7.             "pageUrl""enter the site url",  
  8.             "customActions": {  
  9.                 "716b612c-e184-4ccc-a24e-604a7c837821": {  
  10.                     "location""ClientSideExtension.ApplicationCustomizer",  
  11.                     "properties": {  
  12.                         "Top""DRONZER10",  
  13.                         "Bottom""Nilanjan Mukherjee"  
  14.                     }  
  15.                 }  
  16.             }  
  17.         },  
  18.         "ext2": {  
  19.             "pageUrl""enter the site url",  
  20.             "customActions": {  
  21.                 "716b612c-e184-4ccc-a24e-604a7c837821": {  
  22.                     "location""ClientSideExtension.ApplicationCustomizer",  
  23.                     "properties": {  
  24.                         "Top""DRONZER10",  
  25.                         "Bottom""Nilanjan Mukherjee"  
  26.                     }  
  27.                 }  
  28.             }  
  29.         }  
  30.     }  
  31. }  
Update the package-solution.json file as
  1. {  
  2.     "$schema""https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",  
  3.     "solution": {  
  4.         "name""ext-2-client-side-solution",  
  5.         "id""8e90fd7b-a799-4834-82c6-d55b530af66c",  
  6.         "version""4.0.0.0",  
  7.         "includeClientSideAssets"true,  
  8.         "isDomainIsolated"false,  
  9.         "developer": {  
  10.             "name""",  
  11.             "websiteUrl""",  
  12.             "privacyUrl""",  
  13.             "termsOfUseUrl""",  
  14.             "mpnId"""  
  15.         },  
  16.         "features": [{  
  17.             "title""Application Extension - Deployment of custom action.",  
  18.             "description""Deploys a custom action with ClientSideComponentId association",  
  19.             "id""e53cf4f6-9ca9-4060-8f09-bca3286ecf18",  
  20.             "version""1.0.0.0",  
  21.             "assets": {  
  22.                 "elementManifests": ["elements.xml"]  
  23.             }  
  24.         }]  
  25.     },  
  26.     "paths": {  
  27.         "zippedPackage""solution/ext-2.sppkg"  
  28.     }  
  29. }  
Update the elements.xml file as,
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <Elements  
  3.     xmlns="http://schemas.microsoft.com/sharepoint/">  
  4.     <CustomAction  
  5. Title="Ext2"  
  6. Location="ClientSideExtension.ApplicationCustomizer"  
  7. ClientSideComponentId="716b612c-e184-4ccc-a24e-604a7c837821"  
  8. ClientSideComponentProperties="{"Top":"DRONZER10","Bottom":"Nilanjan Mukherjee"}"></CustomAction>  
  9. </Elements> 
You can test the extension in the local workbench using command gulp serve.
 
For using in sharepoint please package the solution
 
gulp bundle --ship
gulp package-solution --ship
 
Under the SharePoint folder find the ext-2.sppkg file. Here you can right click and then click on reveal in file explorer.
 
Upload the solution in the sharepoint app catalog. From the site content page add the solution. After the solution is added successfully, the extension will be visible in the modern page.
 
If you do any enhancement in the solution please go to the package-solution.json file and update the version before uploading it to the Sharepoint app catalog.