logo
Published on

SPFx and CDN — Configuring the Office 365 CDN Correctly

Every SPFx web part bundle — your JavaScript, CSS, and images — is stored in SharePoint Online and served to users from SharePoint's origin servers. For users in the same region as your tenant, this is fast. For users in Sydney connecting to a tenant hosted in Europe, every page load downloads your bundles over a long-haul connection.
The Office 365 CDN distributes your SPFx assets to Microsoft's global edge network — the same CDN infrastructure that serves Office.com and Teams. Users download from the nearest edge node rather than your tenant's origin. For geographically distributed organisations, this alone produces measurable load time improvements.
This article covers the full configuration: enabling the CDN, adding the right origins, verifying it is working, and diagnosing the common issues.


🗺️ How the Office 365 CDN Works with SPFx

When you deploy an SPFx solution with --ship, the built assets are uploaded to ClientSideAssets in the App Catalog site's document library. By default, SharePoint serves these directly from the App Catalog.

With the CDN enabled and the */ClientSideAssets origin configured, SharePoint registers this library as a CDN origin. Microsoft's CDN crawls and caches all files in the library. When a browser requests an SPFx bundle, the URL resolves to the nearest CDN edge node rather than the SharePoint origin.

The key point: no code change is needed in your SPFx project. The CDN is pure infrastructure — SPFx generates the correct CDN URLs automatically when the CDN is configured.


⚙️ Step 1 — Enable the Office 365 CDN

Connect to SharePoint Online PowerShell:

Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Force
Connect-SPOService -Url "https://contoso-admin.sharepoint.com"

Check the current CDN status:

Get-SPOTenantCdnEnabled -CdnType Public
Get-SPOTenantCdnEnabled -CdnType Private

Enable the Public CDN (required for SPFx assets — they are not user-specific):

Set-SPOTenantCdnEnabled -CdnType Public -Enable $true

When prompted to also enable default origins, answer Yes. This adds the standard SharePoint origins including */MASTERPAGE and */STYLE LIBRARY. You will add the SPFx-specific origin in the next step.


⚙️ Step 2 — Add the SPFx Assets Origin

The default origins do not include ClientSideAssets. Add it explicitly:

# Add the App Catalog's ClientSideAssets folder as a CDN origin
Add-SPOTenantCdnOrigin -CdnType Public -OriginUrl "*/ClientSideAssets"

Verify the origin was added:

Get-SPOTenantCdnOrigins -CdnType Public

You should see */CLIENTSIDEASSETS in the list. Note that it may show as Pending for up to 15 minutes while the CDN crawls and caches the existing files.


⚙️ Step 3 — Verify the CDN Is Active

After the origin shows as Active (not Pending), verify that SPFx assets are being served from the CDN:

  1. Deploy any SPFx solution to the App Catalog
  2. Navigate to a page that uses that web part
  3. Open browser DevTools → Network tab
  4. Filter for .js files matching your web part name
  5. Check the Request URL — it should contain *.cdn.office.net or similar CDN hostname, not *.sharepoint.com

Example of a CDN-served URL:

https://contoso.cdn.office.net/sites/apps/ClientSideAssets/.../<bundle>.js

If you still see sharepoint.com URLs, the CDN origin is either still pending or the assets were cached before the CDN was enabled — redeploy the solution to force a new upload.


⚙️ Step 4 — Custom CDN Origins for Site Assets

Beyond ClientSideAssets, you can add other SharePoint libraries as CDN origins — for static assets like images, fonts, and CSS that your SPFx solution references:

# Add a site's SiteAssets library as a CDN origin
Add-SPOTenantCdnOrigin -CdnType Public `
  -OriginUrl "sites/intranet/SiteAssets"

# Add a specific subfolder
Add-SPOTenantCdnOrigin -CdnType Public `
  -OriginUrl "sites/intranet/SiteAssets/icons"

After adding, reference assets using the CDN URL in your SPFx components:

// Get the CDN URL for a site asset at runtime
const cdnBaseUrl = this.context.pageContext.legacyPageContext?.cdnPrefix ?? '';
const logoUrl = `${cdnBaseUrl}/sites/intranet/SiteAssets/logo.png`;

🔒 Private CDN vs Public CDN

Public CDNPrivate CDN
AuthenticationNo — files are publicly accessibleYes — requires SharePoint auth token
Use caseSPFx bundles, images, CSS, fontsUser-specific or permission-gated assets
SPFx assets✅ Correct choice❌ Adds auth overhead to every asset request
Document libraries❌ Not appropriate✅ For secured documents

For SPFx bundles, always use the Public CDN. SPFx JavaScript files contain no sensitive data — they are code, not content. Adding authentication overhead to every bundle download defeats the performance purpose of the CDN entirely.


⚠️ Common Issues and Fixes

CDN origin shows Pending for more than 30 minutes. This is normal on first setup — the crawler is indexing existing files. If it persists beyond an hour, remove and re-add the origin:

Remove-SPOTenantCdnOrigin -CdnType Public -OriginUrl "*/ClientSideAssets"
Add-SPOTenantCdnOrigin -CdnType Public -OriginUrl "*/ClientSideAssets"

Assets still served from sharepoint.com after CDN is active. The web part was deployed before the CDN was enabled. Redeploy the .sppkg — the App Catalog re-uploads the assets and SharePoint generates new CDN-backed URLs.

CDN returns 404 for a specific asset. The asset was not present in the origin folder when the CDN last crawled it. Wait for the next crawl cycle (usually within minutes of a new upload) or check the file exists in the App Catalog's ClientSideAssets library.

SPFx workbench loads assets from CDN in read mode but localhost in serve mode. This is correct behaviour. gulp serve always uses localhost — the CDN is only active for deployed (--ship) bundles.


📋 CDN Configuration Checklist

  • Public CDN enabled: Get-SPOTenantCdnEnabled -CdnType Public returns True
  • */ClientSideAssets origin added and status is Active
  • Post-deployment: network requests for .js bundles resolve to *.cdn.office.net
  • Custom site asset libraries added as origins where applicable
  • Private CDN not used for SPFx bundles (public is correct)

✅ Summary

  • Enable the Office 365 Public CDN via Set-SPOTenantCdnEnabled -CdnType Public -Enable $true.
  • Add */ClientSideAssets as a CDN origin — this covers all SPFx deployed bundles.
  • No code changes required in your SPFx project — CDN URLs are generated automatically on deployment.
  • Use Public CDN for SPFx assets — adding Private CDN authentication overhead defeats the performance goal.
  • If assets are still served from sharepoint.com after enabling the CDN, redeploy the solution to force fresh CDN-backed URLs.
  • Allow up to 15 minutes for a new origin to move from Pending to Active.

Happy coding!

Ad image