Setting Up PnPjs Context Accessors for SharePoint and Microsoft Graph in SPFx

This article provides a technical overview of how to create and manage context-aware singleton accessors for both SharePoint and Microsoft Graph using the PnPjs library in a SharePoint Framework (SPFx) project. The code pattern presented ensures efficient initialization and reuse of SPFI and GraphFI instances, which are critical for performing REST operations against SharePoint and Graph APIs.

Objective

To enable a clean, reusable, and maintainable method for instantiating PnPjs clients (spfi, graphfi) tied to the current SPFx WebPartContext, avoiding redundant initializations and ensuring optimal performance across components.


Technologies Used

  • SPFx: Provides the WebPartContext required to authenticate and authorize API calls.
  • PnPjs: A fluent JavaScript API for SharePoint and Graph, simplifying REST operations.
  • TypeScript: Enables strong typing and development-time tooling.

Core Concepts and Implementation

1. Importing Required Modules

The code starts by importing essential packages from @pnp/sp and @pnp/graph and includes side-effect imports to extend the functionality of the PnPjs core.

import { spfi, SPFI, SPFx as spSPFx } from "@pnp/sp";
import { graphfi, GraphFI, SPFx as graphSPFx } from "@pnp/graph";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import "@pnp/sp/batching";

These side-effect imports (like @pnp/sp/items) are necessary to enable chained calls like .web.lists.getByTitle().items.add().


2. Singleton Pattern for SP and Graph Clients

The use of var and simple checks (if (_sp === undefined || _sp === null)) ensures that these objects are only created once during the application lifecycle.

var _sp: SPFI;
var _graph: GraphFI;

This pattern is crucial for performance and memory efficiency in SPFx solutions where multiple components may need to access the same context.


3. getSP Function

This function returns an instance of the SharePoint Fluent Interface (SPFI) configured for the current SPFx context.

export const getSP = (context?: WebPartContext): SPFI => {
  if (_sp === undefined || _sp === null) {
    _sp = spfi().using(spSPFx(context as ISPFXContext));
  }
  return _sp;
};

  • spfi() creates the base instance.
  • .using(spSPFx(...)) applies the context, which enables token-based authorization using the current user’s credentials.

4. getGraph Function

Similarly, getGraph initializes and returns a context-bound Microsoft Graph client (GraphFI):

export const getGraph = (context?: WebPartContext): GraphFI => {
  if (_graph === undefined || _graph === null) {
    _graph = graphfi().using(graphSPFx(context as ISPFXContext));
  }
  return _graph;
};

This allows access to resources such as user profiles, Teams, Planner, etc., via Microsoft Graph API endpoints.


5. Logging Note

Although the comments mention the need for @pnp/logging, it is not explicitly used in the code snippet. If extended, this would allow debugging output based on different log levels, which is often essential during development.


Integration Reference

For full context and usage examples, refer to the official PnPjs documentation:
Getting Started with PnPjs: https://pnp.github.io/pnpjs/getting-started/


Summary Table

AspectDetails
PurposeContext-aware singleton for SharePoint and Graph clients
Key Libraries@pnp/sp, @pnp/graph, @microsoft/sp-webpart-base
Output ObjectsSPFI, GraphFI
Authentication MethodVia SPFx(context) helper
Usage PatternSingleton with lazy instantiation
Optimization BenefitPrevents reinitialization and ensures token reuse
Dependency ImportsLists, items, webs, batching
Documentation ReferencePnPjs Getting Started

By adopting this pattern, SPFx developers can centralize context configuration, improve code readability, and build scalable web parts or extensions that interact efficiently with SharePoint and Microsoft 365 services.

Edvaldo Guimrães Filho Avatar

Published by