A client had a requirement recently to remotely provision site collection (classic) with a couple of modern pages, a few libraries with custom content types and having the “Orange” out of the box modern theme applied to the site.
Provisioning of the site along with the modern pages is quite straightforward - thanks to the PnP community!
Where I faced a problem was applying an OOB modern theme. As Jõao mentions in his blog post — on classic site collections, a random colour is picked for the modern bits (modern pages, libraries etc).
So, I thought of looking into Set-PnPWebTheme cmdlet and hence the underlying CSOM method tenant.SetWebTheme. This cmdlet is great for custom themes however, as Mikael mentions in one of his blog posts, it cannot be used for OOB modern themes. Same is the case for the Set-SPOWebTheme cmdlet.
There are 2 solutions to solve this problem:
- Using the spcolor file — In that same blog post under the “PnP Provisioning template” section Mikael mentions a way to solve the problem I was having. I used this as this is the easiest solution while provisioning classic sites using PnP site templates.
- Using REST API — ApplyTheme REST endpoint (thanks for the network panel tip Leo Siddle). This endpoint accepts the theme data (colours) as JSON and applies the theme.
Details of the solution
This blog explains the second approach which can be used in the following scenarios
- A separate step after provisioning the site using PnP site templates or
- When site provisioning is being done without using PnP site templates.
All we do is call the API in a console application. The application requires site url, credentials and the colour of the OOB modern theme that needs to applied.
Vadim has written a great blog post on how to create a Http client for SharePoint and execute SharePoint REST API. I’m using the same one with one extra method which accepts JSON string as the payload.
There is a helper method which returns the required theme JSON as string. I have extracted these from the network panel by navigating through each of the modern themes.
As always the entire code for this is in a GitHub repository here.
Using app registration
If the authentication needs to be done via an app registration then instead of the request digest, an authentication token must be added to the headers of the httpclient object. One of my other GitHub repositories has some methods on how to do achieve that.