Static content hosting
Configure Rayfin static hosting, asset access, package version declarations, deployment commands, and the 100 MB archive limit.
Static hosting serves your built frontend from the same Fabric app as the Rayfin backend. rayfin up publishes static content; rayfin dev runs the frontend locally and never publishes static assets.
How it works
- Rayfin reads
services.staticHostingfromrayfin/rayfin.yml. - The CLI resolves the frontend package directory from
pathandroot. - The CLI refreshes the frontend
.env.localwhen it can detect the framework. - Rayfin runs
buildCommandunless the command is skipped. - The output folder is validated and packaged into a compressed archive.
- The archive is uploaded to the Fabric app.
- The returned hosting URL is recorded in
rayfin/.deployments.json. - The hosting origin is registered in
allowedRedirectUrisfor Fabric SSO.
Configure static hosting
services:
staticHosting:
enabled: true
path: packages/frontend
folder: dist
buildCommand: npm run build:fabric
indexDocument: index.html
assetAccess: protected| Option | Required | Default | Description |
|---|---|---|---|
enabled | Yes | false | Enables static hosting. |
path | No | Project root | Frontend package directory relative to the app root. Use this for npm workspaces such as packages/frontend. |
root | No | path or project root | Build working directory relative to path when path is configured. Kept for older flat layouts. |
folder | Yes | dist | Built asset folder relative to the resolved static-hosting directory. |
buildCommand | No | — | Command Rayfin runs before packaging, for example npm run build:fabric. |
indexDocument | No | — | Default document for directory requests, for example index.html. |
assetAccess | Yes for new posture-aware deploys | protected in new projects | protected requires Fabric sign-in before hosted assets load; public lets anyone with the link load assets. New in 1.35.1 |
assetAccess replaces the older anonymousAccess authoring property. The CLI removes services.staticHosting.anonymousAccess when it records the new value. Non-interactive rayfin up runs such as --yes, --json, and CI default a missing posture to protected and write it to rayfin.yml instead of failing. New in 1.35.1
Choose protected or public assets
| Value | Meaning |
|---|---|
protected | Visitors must sign in with Fabric before hosted assets load. This is the recommended default. |
public | Anyone with the link can load the hosted static assets. APIs and data permissions still apply. |
Do not combine assetAccess: public with embedded.only: true. An embedded-only app has no standalone public surface.
Workspace frontend example
The 1.36 universal app uses an npm workspace and points static hosting at the frontend package:
services:
staticHosting:
enabled: true
path: packages/frontend
folder: dist
buildCommand: npm run build:fabric
indexDocument: index.html
assetAccess: protectedThe archive path is packages/frontend/dist, not a root dist directory.
Flat frontend example
Flat templates can omit path:
services:
staticHosting:
enabled: true
folder: dist
buildCommand: npm run build:fabric
indexDocument: index.html
assetAccess: protectedDeploy static content
A full deploy builds and uploads static content:
npx rayfin upFor static-only updates after an initial deploy:
npx rayfin up staticapp deploySkip the build step only when the output folder already contains the production build you want to publish:
npx rayfin up staticapp deploy --skip-buildstaticapp deploy requires an existing remote deployment. Run npx rayfin up once first.
Develop without publishing static content
Use the development loop for frontend iteration:
npm run devThat runs rayfin dev, starts Vite locally, and does not publish static assets.
Existing automation can still skip the static phase while running the deploy workflow:
npx rayfin up --exclude-services staticHostingRuntime settings still sync, so the backend remains aligned with rayfin.yml.
Declared package versions
Every runtime-settings write declares packageVersions for the deploying CLI, and includes @microsoft/rayfin-auth when the frontend package has it installed. New in 1.35.1 The control plane uses these declarations to reject static-hosting deployments from a CLI too old to record the asset-access posture.
Run a dry run to see the versions that would be sent:
npx rayfin up --dry-runStatic-hosting access control also checks that an installed @microsoft/rayfin-auth is at least 1.35.0-alpha.1541. New in 1.35.1 If an older Rayfin auth package is present, the CLI prompts to upgrade Rayfin packages together before anything is published.
Redirect URIs
When static hosting is enabled, rayfin up registers the deployed hosting origin with services.auth.allowedRedirectUris. rayfin dev separately registers the local frontend origin and retained port aliases. See Redirect URIs.
Archive limit
The compressed static archive must be at most 100 MB. If the archive is too large:
- Exclude source maps from production output.
- Optimize or move large images and binary assets.
- Store large user-facing files in a service designed for file storage instead of bundling them into the app shell.
- Re-run
npx rayfin up staticapp deployafter rebuilding.
Local Vite adapter
Templates register rayfinLocalDev() from @microsoft/rayfin-local-dev/vite. The adapter is for rayfin dev, not production builds. It serves local rayfin.config.json, proxies backend and Functions routes, and supports local automatic sign-in for protected static assets. See Develop locally.
Troubleshooting
| Symptom or error | Fix |
|---|---|
| Static folder not found | Check path, root, and folder; run the build command manually. |
| Empty static folder | Confirm the build command writes files to the configured output folder. |
Compressed package size (...) exceeds the 100 MB limit. | Reduce the compressed output size and redeploy. |
Static hosting is enabled but services.staticHosting.assetAccess is not set in rayfin.yml | Add assetAccess: protected or assetAccess: public, or run rayfin up interactively. |
Invalid static hosting posture: 'services.staticHosting.embedded.only: true' cannot be combined with 'services.staticHosting.assetAccess: public' because an embedded app has no standalone surface to make public. | Use assetAccess: protected or set embedded.only: false. |
| No remote endpoint configured | Run npx rayfin up once before npx rayfin up staticapp deploy. |
In my Rayfin project, configure `services.staticHosting` with the correct frontend `path`, `folder`, `buildCommand`, `indexDocument`, and `assetAccess: protected` unless I explicitly need public assets. Run `npx rayfin up --dry-run` to validate the static inputs and declared packageVersions, then deploy with `npx rayfin up` and report `deployment.hostingUrl` from `npx rayfin up status --json`.