Building the NavigationMenu React Component for SPFx Top Placeholder

In the previous article we implemented a SharePoint Framework (SPFx) Application Customizer that injects a React component into the Top placeholder of the SharePoint page. Now, let’s dive into the core of this customization: the NavigationMenu component.

This component is responsible for rendering a menu based on configuration or list data passed via props.


Component Design

Expected Props

In the previous class, NavigationMenu was invoked as:

<NavigationMenu
  type="Default"
  ListTitle="TopMenu"
  AppContext={this.context}
  siteUrl="https://sharepoint.com/sites/site"
/>

This suggests the component is dynamic and context-aware, receiving:

  • type: A string to determine menu style or variant
  • ListTitle: The SharePoint list that contains menu items
  • AppContext: The current SPFx context, including spHttpClient, page context, etc.
  • siteUrl: The full URL of the target site where the list is located

Example Implementation of NavigationMenu.tsx

Here’s a possible technical implementation of NavigationMenu:

import * as React from 'react';
import { useEffect, useState } from 'react';
import { IContextInfo } from './types';
import { SPHttpClient } from '@microsoft/sp-http';

export interface INavigationMenuProps {
  type: string;
  ListTitle: string;
  AppContext: IContextInfo;
  siteUrl: string;
}

interface IMenuItem {
  Title: string;
  Url: string;
}

const NavigationMenu: React.FC<INavigationMenuProps> = (props) => {
  const [items, setItems] = useState<IMenuItem[]>([]);

  useEffect(() => {
    loadMenuItems();
  }, []);

  const loadMenuItems = async () => {
    const endpoint = `${props.siteUrl}/_api/web/lists/getbytitle('${props.ListTitle}')/items?$select=Title,Url`;
    const response = await props.AppContext.spHttpClient.get(endpoint, SPHttpClient.configurations.v1);
    
    if (response.ok) {
      const json = await response.json();
      setItems(json.value);
    } else {
      console.error("Failed to fetch menu items");
    }
  };

  return (
    <nav className={`custom-menu custom-menu-${props.type}`}>
      <ul>
        {items.map((item, index) => (
          <li key={index}><a href={item.Url}>{item.Title}</a></li>
        ))}
      </ul>
    </nav>
  );
};

export default NavigationMenu;


Technical Breakdown

ElementDescription
useEffect()Fetches menu items once the component is mounted
SPHttpClientProvided by AppContext, used to call SharePoint REST API
ListTitleIdentifies which list to pull data from
siteUrlBase site to construct the API call
setItems()Updates React state with menu entries
custom-menu-${props.type}Enables dynamic theming via CSS classes

Expected SharePoint List Structure

For this menu to work correctly, the SharePoint list named TopMenu should have at least the following columns:

Column NameInternal NameType
TitleTitleText
UrlUrlHyperlink or Text

These columns are referenced in the REST API call:
/_api/web/lists/getbytitle('TopMenu')/items?$select=Title,Url


Styling the Menu

Basic CSS structure (can be extended for themes or variants):

.custom-menu {
  background-color: #f3f3f3;
  padding: 10px;
}

.custom-menu ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 15px;
}

.custom-menu li a {
  text-decoration: none;
  font-weight: bold;
  color: #0078d4;
}


Summary Table

FeatureDescription
NavigationMenuReact component rendering menu links
AppContext.spHttpClientUsed to query the SharePoint list
siteUrlAllows querying across site collections
ListTitleIdentifies which SharePoint list to use
typeOptional styling flag
IMenuItem interfaceDefines the structure of each menu item
REST API Used/_api/web/lists/getbytitle('List')/items?$select=Title,Url

Related Concepts

Edvaldo Guimrães Filho Avatar

Published by