Managing concurrent tenant-wide and site collection-scoped SharePoint Framework deployments

I was recently asked a question on the discussion forum for my Pluralsight course “Creating Deployment Packages for SharePoint Framework Projects” about how to manage concurrent tenant-wide and site collection-scoped deployments for SharePoint Framework projects, specifically web parts. As you may know, SharePoint offers site collection app catalogs as a way to decentralize the management of SharePoint Framework solutions (as well as Add-ins built using the Add-in model…is anyone out there still building these?) and scope the deployment of a solution to a single site. This may be useful if you want to leverage separate site collections for staging and testing before deploying a solution to your tenant’s production app catalog. But what if your staging and testing site collections reside within the same production tenant? Will there be duplicate entries for your web part — one for the site collection-scoped deployment and another for the tenant-wide deployment? How does SharePoint manage this?

The site collection-scoped deployment always takes precedence

As long as a version of your solution package’s .sppkg file is uploaded to a site collection’s app catalog, the assets associated with that version will be the only version available to you within that site collection, regardless of whether or not a newer version is deployed tenant-wide. This is true even if you do not currently have the app associated with your solution package installed in that site collection. To demonstrate this, I created a simple web part project based on the Yeoman generator’s HelloWorldWebPart that simply renders TEST. I packaged and deployed this solution to a site collection app catalog, installed it within my TEST site collection using the “Add an app” link, then added my web part to a page:

After that, I created a new version of the solution that updates the web part to render PROD instead. I packaged and deployed this new version tenant-wide from my tenant’s app catalog and added it to a page outside my TEST site collection:

I then went back to my TEST site collection and confirmed that I could still only see one instance of the “ScopeTest” web part in that site:

Adding it to the page again confirmed that this was indeed still my TEST web part:

How can I access the version that is deployed tenant-wide from this site?

One might assume that in order to have access to the tenant deployed PROD version of my web part from my TEST site collection, all I would need to do is remove the installed app instance associated with my TEST web part from that site. However, after I did this, I went to add my “ScopeTest” web part to the page again (expecting the tenant deployed version to be available) and found that it wasn’t there for me to add at all:

It turns out that I had to first delete my TEST web part solution’s .sppkg file from my site collection app catalog. After I did that, I returned to the home page of the site and noticed my TEST web part instances had been replaced with PROD instances automatically:

Application customizer extensions behave a little differently

I performed the same steps with an application customizer extension that renders a simple TEST or PROD header in the “Top” placeholder on the page. I began by deploying the TEST version to my TEST site collection. After installing the app to the site, I saw the TEST header I expected to see:

After that, I created a new version of the solution and updated the extension to render PROD on a red background instead. I packaged and deployed this new version tenant-wide from my tenant app catalog and it appeared on this page outside my TEST site collection:

But when I went back to my TEST site collection, I saw something different:

It appears that in addition to the initial site collection-scoped deployment, the site also picks up the reference to the tenant deployed extension from the Tenant Wide Extensions list in the tenant’s app catalog site, which causes it to render the version of the extension from the site collection app catalog again.

And similar to the behavior I saw after removing the installed app instance associated with my TEST web part from that site collection, uninstalling the app instance associated with my TEST extension (but leaving the .sppkg file in the site collection app catalog) caused no extensions to be rendered on the page — neither the site collection-scoped version nor the tenant deployed version:

Once again, I had to delete my TEST extension solution’s .sppkg file from the site collection app catalog. After I did that, I returned to the home page of the site and saw the PROD extension was now being rendered:

Final thoughts

Once you learn the nuances of how SharePoint deconflicts site collection-scoped and tenant-wide deployments for SharePoint Framework solution packages, you can determine which approach works best for you when managing the two types of deployments concurrently for a solution package within a single tenant. If possible, you might consider configuring tasks in your CI/CD pipeline to uninstall and remove any solution packages from site collection app catalogs before they are deployed tenant-wide. You can learn more about CI/CD pipelines for enterprise SharePoint Framework development in my Pluralsight course “Scaling up SharePoint Framework Development for Enterprises.”