Skip to content


The ProviderHostedRequestContext enables the creation of provider-hosted add-ins built in node.js to use pnpjs to interact with SharePoint. The context is associated to a SharePoint user, allowing requests to be made by the add-in on the behalf of the user.

The usage of this class assumes the provider-hosted add-in is called from SharePoint with a valid SPAppToken. This is typically done by means of accessing /_layouts/15/AppRedirect.aspx with the app's client ID and app's redirect URI.

Note: To support concurrent requests by different users and/or add-ins on different tenants, do not use the SPFetchClient class. Instead, use the more generic NodeFetchClient class. The downside is that you have to manually configure each request to use the desired user/app context.

import { sp, SPRest } from "@pnp/sp/presets/all";
import { NodeFetchClient, ProviderHostedRequestContext } from "@pnp/nodejs";

// configure your node options
    sp: {
        fetchClientFactory: () => {
            return new NodeFetchClient();

// get request data generated by /_layouts/15/AppRedirect.aspx
const spAppToken = request.body.SPAppToken;
const spSiteUrl = request.body.SPSiteUrl;

// create a context based on the add-in details and SPAppToken
const ctx = await ProviderHostedRequestContext.create(spSiteUrl, "{client id}", "{client secret}", spAppToken);

// create an SPRest object configured to use our context
// this is used in place of the global sp object
const userSP = new SPRest().configure(await ctx.getUserConfig(), spSiteUrl);
const addinSP = new SPRest().configure(await ctx.getAddInOnlyConfig(), spSiteUrl);

// make a request on behalf of the user
const user = await userSP.web.currentUser();
console.log(`Hello ${user.Title}`);

// make an add-in only request
const app = await addinSP.web.currentUser();
console.log(`Add-in principal: ${app.Title}`);