How to Create Modern Pages Using PnPJS in SharePoint Online


We can interact with SharePoint in different ways based on the requirement and the platform we choose for development. Every approach helps us with SharePoint development in an easier and more efficient way.
We have JSOM, CSOM, Rest APIs, PowerShell commands, and so on. Now, in recent days PnP JS is one of the most-used approaches used by developers for SharePoint Development.
Let’s see how to integrate PnP JS in a SharePoint Framework application and create modern pages with its help.

Integrating PnP JS in SPFx applications

Once you have created the SharePoint framework application, it can be any type, either React, Angular, JavaScript. Open your command prompt and point to the project location and run the below commands to install the necessary dependencies to integrate PnP JS.
  1. npm install @pnp/logging @pnp/common @pnp/odata @pnp/sp –save  
Now in your code, import the PnP root object, like shown below:
  1. import { sp } from "@pnp/sp";  
PnP JS internally frames the REST API requests so we need to pass the context of the project to get the web/user related details of the web where it is running.
The best place to do this is in the onInit() method. In your onInit() method, add the below piece of code:
  1. sp.setup({    
  2.    spfxContext: this.context    
  3. });     
We are done with the basic PnP JS integration.

Creating client-side pages using PnP JS

Here, we will discuss a step-by-step implementation for this.
Step 1
Import the below relevant objects at the top of your file:
  1. import { sp } from "@pnp/sp";    
  2. import "@pnp/sp/webs";    
  3. import "@pnp/sp/clientside-pages/web";    
  4. import { PromotedState } from "@pnp/sp/clientside-pages";     
Step 2
The below code snippet helps to create the modern site page:
  1. const page = await sp.web.addClientsidePage("pageName""Page Title""Article");  
Step 3
If you want to create a temporary modern site page and let the user set the pagname while setting the title, as with the Out of the box functionality. Just specify empty values for pagename and page title, like shown below:
  1. const page = await sp.web.addClientsidePage("""""Article");  
Now the page will be created, but pagename is temporary and the title will be empty. Once the user opens the page and edits the title of the page, the title will be set as pagename.
Step 4
If you want to save the page as a draft, use the same method as below by passing the “publish” parameter as false.
Step 5
If you want to publish the page, use the save method like below by passing the “publish” parameter as true.
The default value for publishing in the save function is true.
Step 6
If you want to promote this published page as News, use the below code snippet:
  1. page.promoteToNews();  
Step 7
We can even specify the publishing status while creating the page itself from the version 2.0.4 of PnP Js. Here is the code to do that, where you can see one additional parameter to pass the Promoted State
  1. const page = await sp.web.addClientsidePage("pageName""Page Title""Article" , PromotedState.PromoteOnPublish);  
Now if you just save the page in publish mode, it will be promoted to news by default. We no need to call the “promoteToNews()” method explicitly.

Update custom page properties using PnP JS

As of now, there are no methods available directly to update the page properties, but there is a simple workaround.
Basically, Site Pages is also a List, so we can update the properties of the Site Pages like we update the List Item. Let’s see the step by step implementation below:
Step 1
Create the site page as discussed above and get the item id of the created page using the “json” object in pageresult. The problem here is we don’t get this value in the compile time, but we will get it in the run time. We will get a typecasting error if it is directly accessed.
Step 2
Create a temporary object and declare it as any type, so we can skip the typecasting error.
  1. let tempPage: any = page; //page object got from above implementation.    
  2. let pageItemId: number=tempPage.json.Id;     
Debug/console the json object and get useful values as per the requirement. You can also get the Absolute URL of the page, as shown below:
  1. let pageUrl:string = tempPage.json.AbsoluteUrl  
Step 3
Import the list interface as shown below:
  1. import "@pnp/sp/lists";  
Step 4
Update the page item like updating a list item, the list name will be “Site Pages”.
  1. await sp.web.lists.getByTitle("Site Pages").items.getById(pageItemId).update({    
  2.    FieldName1: FieldValue1,    
  3.    FieldName2: FieldValue2,    
  4. });     


I hope this article helps you to understand how to work with client-side pages using PnP JS. If you have any questions/issues about this article, please let me know in the comments.