Bridge · #427
A demo, framed anywhere
/embed/<slug> renders one demo with no chrome around it — no header, no footer, no navigation — so it can live inside another page. All 289 assets have one, prerendered at build time so a framed demo paints without waiting on a render — 289 extra pages in the build, which is a real cost and is reported on the build page rather than hidden. A new asset still gets its embed without a change to the route.
The markup
<!-- Inline in a doc --> <iframe src="https://<host>/embed/prism-switch" title="Prism Switch — Motif UI" width="100%" height="320" loading="lazy" style="border:1px solid rgba(255,255,255,.08);border-radius:16px" ></iframe> <!-- Card in a sidebar --> <iframe src="https://<host>/embed/prism-switch" title="Prism Switch — Motif UI" width="360" height="240" loading="lazy" style="border:1px solid rgba(255,255,255,.08);border-radius:16px" ></iframe> <!-- Full-width hero --> <iframe src="https://<host>/embed/prism-switch" title="Prism Switch — Motif UI" width="100%" height="420" loading="lazy" style="border:1px solid rgba(255,255,255,.08);border-radius:16px" ></iframe>
The title matters: an untitled frame is announced as just “frame” by a screen reader. The embed page carries the same attribution link as the live demo, with target="_top" so a click escapes the frame.
Headers the embed route sets
- Content-Security-Policyframe-ancestors *
- X-Robots-Tagnoindex
The frame policy says out loud that the route exists to be framed; without it a future default CSP would silently break every embed. Noindex keeps the near-identical demo-only pages out of search results, where they would compete with the asset pages that explain them. A per-site allowlist would need a server reading Origin, which this build does not have.
Reduced motion inside the frame
An embed honours prefers-reduced-motion the same way the site does: the stylesheet collapse applies inside the frame, the shell reads the preference and reflects it on the frame (a data-prefers-reduced-motion attribute), and scenes that drive motion from JavaScript read the same media query. A reader who asked the system for less motion gets a still scene in an embed, not a frame that keeps moving on someone else's page. This is documented rather than promised silently — the rule lives in the motion contract and the scenes carry their branch in their own body.
Live frame
This is the real route, framed by this page exactly as a third-party page would frame it.
What a static build cannot enforce
- An allowlist of embedding sites. Restricting frames to partners means inspecting the Origin header on every request, which needs a server. Today anyone can frame any demo, and the page says so instead of implying a partner programme.
- Frame-busting protection. Related, and equally out of reach without a runtime.
- Per-site analytics. Nothing here counts embeds, so no page on this site claims an embed figure.