Skip to content

Deployment reference ​

This page lists the technical deployment options for RSPFx: CDN behavior matrix, skipFeatureDeployment scope, catalog URLs, environment variables, CI steps, and troubleshooting.

For the step-by-step deployment workflow see docs/deployment.md.

For build outputs see docs/building-packages.md and ZIP layout reference/FORMATS.md.

Pipeline ​

rspfx build     → dist/ + release/manifests + release/assets   (no .sppkg)
rspfx package   → sharepoint/solution/<name>.sppkg            (implies build)
rspfx deploy    → upload .sppkg to app catalog via REST        (implies package)
CommandProducesFlags
rspfx builddist/<bundle>.js + release/manifests/*.manifest.json + release/assets/*--no-minify, --sourcemap
rspfx packagesharepoint/solution/<name>.sppkg from paths.zippedPackage--no-build
rspfx deployPackages then POST to catalogrequires RSPFX_ACCESS_TOKEN + RSPFX_APP_CATALOG_URL

config/package-solution.json paths.zippedPackage is authoritative; paths in plugin options override defaults paths.srcDir, paths.webpartsDir, etc. (packages/core/src/config.ts:54).

Catalog scope and skipFeatureDeployment ​

CatalogURL patternScope
Tenant App Cataloghttps://{tenant}.sharepoint.com/sites/appcatalogEvery site — recommended
Site Collection App Cataloghttps://{tenant}.sharepoint.com/sites/<site>/_layouts/15/tenantAppCatalog.aspxSingle site only
skipFeatureDeploymentBehavior
true (scaffold default)Catalog shows Deploy; solution available on all sites without per-site Add an app; required for Sync to Teams
falseEach site owner must Site Contents → Add an app → <solution>; use for staged rollouts

See config/package-solution.json solution.skipFeatureDeployment and solution.features (feature_<id>.xml + .config.xml).

CDN matrix ​

includeClientSideAssetscdnBasePathManifest internalModuleBaseUrls.sppkg ClientSideAssets/Action
true (default)""['HTTPS://SPCLIENTSIDEASSETLIBRARY/']Bundles embeddedNone — SharePoint serves from catalog
false""[] or emptyNo ClientSideAssets/Fails unless self-hosted; avoid
false or true"https://cdn.contoso.com/<name>/"["https://cdn.contoso.com/<name>/"]Embedded but ignored when CDN setUpload release/assets/* to that CDN
true + non-empty cdnBasePathNon-emptyCDN URL winsEmbeddedCDN URL used

cdnBasePath is config/write-manifests.json cdnBasePath; toolchain appends trailing / if missing (packages/manifest-generator/src/component-manifests.ts:52). Schema: https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json.

Environment variables ​

Single home is docs/commands.md#environment-variables; deployment uses:

VariableUse
RSPFX_ACCESS_TOKENBearer token for rspfx deploy (apps/cli/src/commands/deploy.ts:120); 120 s timeout
RSPFX_APP_CATALOG_URLCatalog URL https://{tenant}.sharepoint.com/sites/appcatalog
RSPFX_LOG_LEVELerror | warn | info | debug | trace
SPFX_SERVE_TENANT_DOMAINFallback for dev.tenantUrl in serve.json {tenantdomain} expansion

Resolution for catalog URL: config.deploy.appCatalogSiteUrl → RSPFX_APP_CATALOG_URL → prompt. Without RSPFX_ACCESS_TOKEN, rspfx deploy prints manual steps and exits 0.

config/serve.json string values support dotenv + shell expansion: ${VAR}, ${VAR:-default}, $VAR, and {tenantdomain} replaced by dev.tenantUrl / SPFX_SERVE_TENANT_DOMAIN / --tenant (packages/core/src/config.ts:138).

CI ​

yaml
steps:
npm ci
yaml
  - run: rspfx doctor
  - run: rspfx package
  - upload: sharepoint/solution/*.sppkg
  # or automated:
  # - run: RSPFX_ACCESS_TOKEN=${{ secrets.SPFX_TOKEN }} RSPFX_APP_CATALOG_URL=https://contoso.sharepoint.com/sites/appcatalog rspfx deploy

Cache node_modules and .rspack-cache between runs. rspfx doctor exits 1 on failure (apps/cli/src/commands/doctor.ts).

Troubleshooting ​

SymptomFix
No web part or extension bundles foundsrc/webparts/<name>/ missing *.manifest.json or entrypoint — see docs/project-structure.md
Bundle 404 in workbench / pageBundle name vs entryModuleId mismatch — default: folder name = bundle key (packages/dev-runtime/src/project.ts:737)
External 'X' could not be resolvedexternals key not in node_modules — remove or add X
Can't resolve 'XxxWebPartStrings'localizedResources pattern must contain {locale} (packages/manifest-generator/src/component-manifests.ts:52)
paths.zippedPackage missingpackage-solution.json must have solution.id, solution.name, paths.zippedPackage
Catalog Sync to Teams missingteams/ not at package time, or includeClientSideAssets: false, or skipFeatureDeployment: false
Invalid Teams manifestteams/manifest.json id ≠ component id, or validDomains missing *.sharepoint.com (packages/templates/src/index.ts:62)
App in Teams but not OutlookWait 10–120 min sync, check personal scope, add *.outlook.office.com to validDomains
API 403Approve in Admin API access (webApiPermissionRequests → AppManifest.xml)
DEPLOY_TIMEOUTCatalog throttling or large .sppkg — retry (120 s timeout)
{tenantdomain} literal in URLNo tenant configured — set dev.tenantUrl or SPFX_SERVE_TENANT_DOMAIN or --tenant
IsValidAppPackage: falseSharePoint OPC parser rejected package — verify AppManifest.xml GUID formatting and ZIP rels — see reference/FORMATS.md §4 (packages/sppkg-builder/src/xml.ts:359)

For .sppkg entry ordering see reference/FORMATS.md §4.

Released under the MIT License.