Add SharePoint web part on modern page before the solution is deployed

Why we add web part on a page before the package is being deployed


I had to do it as part of the provisioning process where we create site from a PnP Core CSharp code and also a PnP template applied from the code, but I had to deploy the solution package with the SPFx web parts later to a site collection application catalog. The main reason I could not deploy the package is indeed the site collection app catalog. SharePoint online ALM apis are available, but they did not support deploy to site collection app catalog at the time of that exercise. I had to add new custom web part on the home page. I did not want to do it with post script after the package is being deployed, but instead I wanted to keep that in only one script that will provision the site, add ghost web part on the page and later when the package is deployed the web part should be functional.


Use PnP-Sites-Core to add web part on modern site page before the SPFx solution package is being deployed


So, we can add web part in advance. It will just be on the page and nonfunctional so it will not be rendered when in display mode. However, the ghost web part can be seen in edit mode. Once the package is deployed the web part should render as normally would. This can be done with the PnP-Sites-Core library and here is the code spinet for that:


using OfficeDevPnP.Core.Pages;
...
var homePage = clientContext.Web.LoadClientSidePage("News.aspx");
if (homePage == null)
{
    this.Logger.Error($"Coudn't find page News.aspx for site {this.SiteInfo.RootUrl}/{this.SiteInfo.SiteUrl}");
    return;
}

var eventsComponent = new ClientSideComponent();
eventsComponent.Id = "d326218b-07de-4653-a001-525639980661";

eventsComponent.Manifest = "{\"$schema\": \"https://dev.office.com/json-schemas/spfx/client-side-web-part-manifest.schema.json\",\"id\": \"d326218b-07de-4653-a001-525639980661\",\"alias\": \"MyInformationEventsWebPart\",\"componentType\": \"WebPart\",\"version\": \"*\",\"manifestVersion\": 2,\"requiresCustomScript\": false,\"preconfiguredEntries\": [{\"groupId\": \"5c03119e-3074-46fd-976b-c60198311f70\", \"group\": { \"default\": \"Other\" },\"title\": { \"default\": \"My Information and Events\" },\"description\": { \"default\": \"Lists the information and events\" },\"officeFabricIconFontName\": \"Sunny\",\"properties\": { \"description\": \"myInformationEvents\"}}]}";

var eventsWebPart = new ClientSideWebPart(eventsComponent);

eventsWebPart.PropertiesJson = "{\"description\":\"myInformationEvents\",\"searchPath\":\"https://contoso.sharepoint.com/sites/xx\",\"enableGlobalContent\":false,\"enableBUSiteOnlyFiltering\":true,\"cardViewSelection\":\"single\"}";

homePage.AddControl(eventsWebPart);
homePage.Save();
homePage.Publish();


As can be seen from the code, the SPFx web part manifest is required to add it, also web part properties can be specified in advance so the web part will be ready and on the page. It is important to use the same manifest.json that will be packaged with the package to ensure that the SharePoint Framework will boot your web part correctly.


Customize your web part in advance


Since the properties for the SPFx web part are stored in the SharePoint site page, we can provision event the web part properties in advance so the web part is ready and just waiting for the package to be deployed. It can be seen from the script I am adding PropertiesJson with specific values I would like to be set up.


Conclusion


With the SharePoint Framework and the new Site Pages the model got more flexible and we have the power to add and pre-configure page controls in advance since the web parts are only strings in a server page until the SPFx JavaScript loads them on the page.