Configuration - SharePoint/PnP-JS-Core GitHub Wiki
The library is designed to work in most scenarios without additional configuration - however there are some cases where it is unavoidable. This article covers those cases and how to perform the necessary setup.
If you have an unpatched version of SharePoint 2013 as discussed in this blog post you will need to set up the library to use verbose OData mode. This is done using the global headers entry. This will apply that header value to all requests sent to the server and avoid the need to configure it on each request.
pnp.setup({
headers: {
"Accept": "application/json;odata=verbose",
}
});
Starting with Version 3.0.* you will need to set up the library in the following way:
pnp.setup({
sp: {
headers: {
"Accept": "application/json; odata=verbose"
}
}
});
For further details check out Moving from 2.0.* to 3.0.*
Similarly you can set any other headers globally that will be set with all requests. This can be helpful for authentication scenarios or custom security filtering in your farm.
pnp.setup({
sp: {
headers: {
"X-Custom": "My Custom Header Value",
"X-Custom2": "My Custom2 Header Value",
}
},
graph: {
headers: {
"X-Custom": "My Custom Header Value",
"X-Custom2": "My Custom2 Header Value",
}
}
});
You can also set the cache settings globally that will be applied to all requests built using the usingCaching method in the chain. See the article on caching for more details on using caching.
pnp.setup({
defaultCachingStore: "session", // or "local"
defaultCachingTimeoutSeconds: 30,
globalCacheDisable: false, // or true to disable caching in case of debugging/testing
enableCacheExpiration: true, // added in 2.0.8
cacheExpirationIntervalMilliseconds: 1000, // added in 2.0.8
});
There are two scenarios requiring you to set a different fetch client, working in nodejs and deploying to an add-in web. Both ways make use of the fetchClientFactory property in the configuration object. This should be set using a factory method taking no parameters and returning a valid instance which implements HttpClientImpl. You can also create a Custom HttpClientImpl should the need arise and return it from the factory.
When operating directly from Node you will need to setup the node fetch client.
import { setup, Web, NodeFetchClient } from "sp-pnp-js";
setup({
sp: {
fetchClientFactory: () => {
return new NodeFetchClient("{site url}", "{client id}", "{client secret}");
}
}
});
let w = new Web("{site url}");
w.select("Title").get().then(w => {
console.log(w);
});
When operating in the context of an add-in web you will need to setup the SPRequestExecutorClient.
import { setup, sp, SPRequestExecutorClient } from "sp-pnp-js";
setup({
fetchClientFactory: () => {
return new SPRequestExecutorClient();
}
});
let w = sp.crossDomainWeb("{add-in web url}", "{host web url}");
w.select("Title").get().then(w => {
console.log(w);
});
The baseUrl property allows you to set a base URL that will be prepended to all requests. It should be absolute. This is also useful when operating without an _spPageContextInfo variable from which we can guess the path.
pnp.setup({
baseUrl: "https://mytenant.sharepoint.com/sites/dev"
});
pnp.sp.web.get().then(w => {
// ...
});
As described here the spfxContext property is used within an SPFx webpart to provide the correct context to the library. It should only be used within those scenarios and can be ignored in classic sites/pages.
export interface LibraryConfiguration {
/**
* Any headers to apply to all requests
*/
headers?: TypedHash<string>;
/**
* Allows caching to be global disabled, default: false
*/
globalCacheDisable?: boolean;
/**
* Defines the default store used by the usingCaching method, default: session
*/
defaultCachingStore?: "session" | "local";
/**
* Defines the default timeout in seconds used by the usingCaching method, default 30
*/
defaultCachingTimeoutSeconds?: number;
/**
* If true a timeout expired items will be removed from the cache in intervals determined by cacheTimeoutInterval
*/
enableCacheExpiration?: boolean;
/**
* Determines the interval in milliseconds at which the cache is checked to see if items have expired (min: 100)
*/
cacheExpirationIntervalMilliseconds?: number;
/**
* Defines a factory method used to create fetch clients
*/
fetchClientFactory?: () => HttpClientImpl;
/**
* The base url used for all requests
*/
baseUrl?: string;
/**
* Used to supply the current context from an SPFx webpart to the library
*/
spfxContext?: any;
}
Added: 2.0.7
Using the configure method you can now create reusable objects with different configurations - or easily store a set of reusable configurations you can apply as needed within your application. You could create and share this configuration object within your application.
// we can supply options and a baseUrl at the root level
const mySP = pnp.sp.configure({
headers: {
"X-Header": "My header"
}
}, "https://mytenant.sharepoint.com");
// now everything we chain off mySP will inherit these options
mySP.web.get().then(w => { /*...*/ });
mySP.web.lists.get().then(l => { /*...*/ });
// we can now also override the settings anywhere in the chain
// you cannot set a new baseUrl at this level
mySP.web.lists.configure({
headers: {
"X-Header": "Replace value"
}
}).get().then(l => { /*...*/ });
// works as well from the root
pnp.sp.web.lists.configure({
headers: {
"X-Header": "Replace value"
},
cache: "no-cache",
credentials: "same-origin",
mode: "cors"
}).get().then(l => { /*...*/ });
export interface ConfigOptions {
headers?: string[][] | { [key: string]: string };
mode?: "navigate" | "same-origin" | "no-cors" | "cors";
credentials?: "omit" | "same-origin" | "include";
cache?: "default" | "no-store" | "reload" | "no-cache" | "force-cache" | "only-if-cached";
}