Provision SPFx Web Parts to Classic Sites – Part 2: Deploy SPFx Web Part to SharePoint Server 2016 App Catalog with WSP

Lets go further with next step how you could make provisioning of SPFx Web Parts to Classic SharePoint Sites inside of your WSP solution package:

  1. Include SPFx Assets & Package inside of WSP
  2. Deploy SPFx Web Part to SharePoint Server 2016 App Catalog with WSP (this blog post)
  3. Install SPFx Web Part to SharePoint Site/Web inside Feature
  4. Include SPFx Web Part inside of Web Template

In previous post we have already done SPFx Web Parts with custom gulp tasks to copy Assets & Package files automatically from SPFx Projects to Module Item of our WSP solution.
So today we start with WSP solution configuration.

First of all we want to create List Instance for our SPFx Web Parts Assets. I choose Assets Library List Template (Template Type = 851).


<ListInstance Title="SPFx Assets" OnQuickLaunch="FALSE" TemplateType="851" FeatureId="4bcccd62-dcaf-46dc-a7d4-e38277ef33f4" Url="SPFxAssets" Description="SPFx Assets Library"></ListInstance>

After that we can configure Module Item in which we already copied SPFx Assets and Package files with gulp tasks created in previous Blog Post. Firstly please include all files into your WSP solution (right click on files / Include In Project).


Then go to Elements.xml file of your Module Item and divide all files into two Modules:

  • first for Assets files (js json): this files will be added to SPFxAssets library created before
  • second for Package files (sppkg): this files will be added to AppCatalog (App Catalog is simple Document Library with some additional fields)
<Elements xmlns="">
  <Module Name="SPFxAssetsM" Url="SPFxAssets">
    <File Path="SPFxAssetsM\WebParts\team-members\633cbe61-210f-4c20-9d7c-267cf12ca3f3.json" Url="WebParts/team-members/633cbe61-210f-4c20-9d7c-267cf12ca3f3.json" Type="GhostableInLibrary" ReplaceContent="True" IgnoreIfAlreadyExists="True" />
    <File Path="SPFxAssetsM\WebParts\team-members\jquery.js" Url="WebParts/team-members/jquery.js" Type="GhostableInLibrary" ReplaceContent="True"  IgnoreIfAlreadyExists="True" />
    <File Path="SPFxAssetsM\WebParts\team-members\team-members-propertycontrolstrings_en-us.js" Url="WebParts/team-members/team-members-propertycontrolstrings_en-us.js" Type="GhostableInLibrary" ReplaceContent="True"  IgnoreIfAlreadyExists="True" />
    <File Path="SPFxAssetsM\WebParts\team-members\team-members-teammemberswebpartstrings_en-us.js" Url="WebParts/team-members/team-members-teammemberswebpartstrings_en-us.js" Type="GhostableInLibrary" ReplaceContent="True"  IgnoreIfAlreadyExists="True" />
    <File Path="SPFxAssetsM\WebParts\team-members\team-members-web-part.js" Url="WebParts/team-members/team-members-web-part.js" Type="GhostableInLibrary" ReplaceContent="True"  IgnoreIfAlreadyExists="True" />
  <Module Name="SPFxAssetsM" Url="AppCatalog">
    <File Path="SPFxAssetsM\WebParts\team-members\team-members.sppkg" Url="team-members.sppkg" ReplaceContent="True"  Type="GhostableInLibrary" IgnoreIfAlreadyExists="True" />

After that we have to create Feature named SPFxFeature with Feature Event Receiver.


Please select Site scope and specify Title and Description. After that include SPFxAssetsLibrary Assets Library and SPFxAssetsM Module Item, both created before.


Then create some static helper class named SPFxHelper with Guid array named SPFxWebParts for specify all of your SPFx Web Parts and DeploySPFxWebPartInAppCatalog static method.

public static class SPFxHelper
    public static Guid[] SPFxWebParts =
        new Guid("abafb8be-4a22-4c0b-9014-8ba08373e273")

    public static void DeploySPFxWebPartInAppCatalog(string cSiteUrl)
        using (SPSite site = new SPSite(cSiteUrl))
            using (SPWeb web = site.OpenWeb())
                SPList list = web.FindListByName("AppCatalog");

                foreach (Guid spfxItem in SPFxWebParts)
                    SPQuery query = new SPQuery
                        Query = "<Where><Eq><FieldRef Name='AppProductID'/><Value Type='Text'>" + spfxItem.ToString("B") + "</Value></Eq></Where>",

                    SPListItem li = list.GetItems(query)[0];
                    li["IsDefaultAppMetadataLocale"] = true;
                    li["IsAppPackageEnabled"] = true;
                    li["IsClientSideSolutionDeployed"] = true;

You could find Guid of your SPFx Web Part inside of package-solution.json config file of your SPFx Web Part Solution.


SPFxWebParts is array of Guids because all of my custom SPFx helper methods work with more than one SPFx Web Part.

DeploySPFxWebPartInAppCatalog method take URL of Site Collection of our App Catalog.
You could create App Catalog Site Collection via SharePoint Central Administration / Apps / Manage App Catalog.


This method then search for Document Library with AppCatalog Internal Name and go through all of our SPFx Web Parts defined in SPFxWebParts Guid Array and set metadata below to all of uploaded SPFx Web Part Packages via Module Item created before:

  • IsDefaultAppMetadataLocale = true
  • IsAppPackageEnabled = true
  • IsClientSideSolutionDeployed = true

And last thing which we have to do is to specify FeatureActivated Feature Event Receiver inside of SPFxFeature created before. There we have to call DeploySPFxWebPartInAppCatalog method from SPFxHelper helper class created before.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
    string cSiteUrl = (properties.Feature.Parent as SPSite).Url;

So thats all. Deploy solution and activate SPFxFeature Site Collection Feature inside of your App Catalog Site Collection. KaBOOM, all apps are installed and all assets files are in SPFx Assets Library inside of App Catalog Site Collection too.

Previous step -> Include SPFx Assets & Package inside of WSP
Next step 
-> Install SPFx Web Part to SharePoint Site/Web inside Feature

Gašper Rupnik


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Powered by

Up ↑

%d bloggers like this: