Deployment and Security
This guide covers a production deployment pattern for StreamMDX with strict CSP, hosted worker assets, and controlled HTML rendering.
Recommended production topology
- Build your app and StreamMDX worker bundle in CI.
- Copy
markdown-worker.jsinto static assets. - Serve docs/app pages and worker from the same origin.
- Keep CSP strict (
worker-src 'self') and avoidblob:.
mkdir -p public/workers
cp node_modules/@stream-mdx/worker/dist/hosted/markdown-worker.js public/workers/markdown-worker.jsThen reference it explicitly:
<StreamingMarkdown worker="/workers/markdown-worker.js" />CSP baseline
A conservative baseline for most deployments:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
worker-src 'self';
connect-src 'self' https:;Notes:
style-src 'unsafe-inline'is often needed for runtime style injection in UI stacks.- If your stack supports nonce-based styles, prefer nonce over unrestricted inline styles.
HTML rendering policy
StreamMDX applies sanitization for untrusted HTML by default. Keep that enabled unless your input source is fully trusted and audited.
Operational policy:
- Enable
features.htmlonly when required. - Prefer render-layer overrides (
htmlElements) over sanitizer allowlist expansion. - Review any allowlist changes as security-sensitive changes.
MDX policy
MDX is code execution by design. Treat MDX input as trusted content unless you have a hardened compilation boundary.
- For user-generated content, keep
features.mdxdisabled. - For trusted editorial content, enforce review + snapshot tests before publish.
Release hardening checklist
- [ ] Hosted worker copied to static path and versioned with app deploy.
- [ ] CSP validated in production response headers.
- [ ]
features.htmlandfeatures.mdxconfigured intentionally (not accidental defaults). - [ ] Regression snapshots updated and reviewed.
- [ ] Perf harness run attached to release notes.
Incident response quick path
If a production issue appears in rendered output:
- Disable risky feature flag (
htmlormdx) first. - Roll back to previous worker bundle + app release.
- Compare regression snapshots to isolate the rendering delta.
- Patch and redeploy with a new snapshot/perf report.
Vercel notes
For this monorepo docs app on Vercel:
- Root Directory:
apps/docs - Build Command:
cd ../.. && npm run docs:build - Install Command:
cd ../.. && npm ci - Output Directory:
apps/docs/out - Include files outside root directory: Enabled
This is required so Vercel can access workspace packages and build the hosted worker.
Custom domain verification
If you attach a custom domain such as stream-mdx.dev, verify all of this after the DNS change:
- apex domain serves valid HTTPS without certificate or handshake errors
wwweither serves cleanly or redirects to the chosen canonical hostname- the docs app and
/workers/markdown-worker.jsstay on the same expected origin - the exported site still builds and serves correctly after the domain cutover
- CSP still permits the hosted worker source you actually ship
Treat a broken TLS handshake as a deployment failure even if DNS already resolves. DNS propagation alone is not enough.