Depending on your situation it might make more sense to use tenant wide deployment and use properties to control the sites which the extension should be active on:
- in config/package-solution.json set skipFeatureDeployment to true
- also in config/package-solution.json an entry should be added to features. You can use a guidgenerator to generate the guid if necessary:
"features": [
{
"title": "Application Extension - Deployment of custom action.",
"description": "Deploys a custom action with ClientSideComponentId association",
"id": "[any guid here]",
"version": "1.0.0.0",
"assets": {
"elementManifests": [
"elements.xml",
"clientsideinstance.xml"
]
}
}
]
- in sharepoint/assets create ClientSideInstance.xml and elements.xml
- ClientSideInstance.xml should be formatted as follows (ComponentId should match the id of your extension in its manifest.json file):
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ClientSideComponentInstance
Title="MyAppCust"
Location="ClientSideExtension.ApplicationCustomizer"
ComponentId="917a86f2-15c1-403e-bbe1-59c6bd50d1e1"
Properties="{"testMessage":"Test message"}">
</ClientSideComponentInstance>
</Elements>
- elements.xml should be formatted as follows (ComponentId should match the id of your extension in its manifest.json file):
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction
Title="MyAppCust"
Location="ClientSideExtension.ApplicationCustomizer"
ComponentId="417feb7a-e193-4072-84b8-52ce58ed024f"
ClientSideComponentProperties="{"testMessage":"Test message"}">
</CustomAction>
</Elements>
- In the main file for your extension (i.e. src/extensions/myAppCust/MyAppCust.ts) add property
allowedSites: string[];
in the interfaces for your extension:
export interface IAlertPopupApplicationCustomizerProperties {
allowedSites: string[];
}
- Also in the main file for the extension, where it makes sense, only allow functionality if the
this.context.pageContext.web.absoluteUrl
is within the allowedSites.
I.e. in onInit() I return early (before doing additional queries) if the current site is not in allowed sites:
@override
public onInit(): Promise<void> {
const absoluteUri = this.context.pageContext.web.absoluteUrl;
// clean up allowed sites
const allowedSites = this.properties.allowedSitesRaw && this.properties.allowedSitesRaw.length
? this.properties.allowedSitesRaw.filter(item => !!item)
: [];
// return early if there are allowed sites specified and the current site is not allowed
if (allowedSites.length && allowedSites.indexOf(absoluteUri) == -1) {
return;
}
}
- Build the solution:
gulp clean && gulp bundle && gulp package-solution --ship
- Deploy the solution to the app catalog.
- Visit Tenant Wide Extensions list (on app catalog site, visit site contents, then tenant wide extensions).
- Select the newly created entry (created when deploying in the App catalog) in the list, select the Items tab in the ribbon, and then select Edit Item.
- Within component properties add the allowedSites property as an array and add any allowed sites (Urls) to the list, ensuring the entry is valid json).
{
allowedSites: [
"https://contoso.sharepoint.com/sites/mySite"
],
testMessage: "Test message"
}
