mf-frame
The host side of an embed: a sandboxed iframe that the embedded app sizes over mf-bridge, and the headers for both apps.
// Host page<MfFrame src="https://agent.example.com/panel" title="Agent panel" maxHeight={900} />// Embedded app (any component that renders inside the frame)useReportHeight(["https://backoffice.example.com"]);// middleware.ts of each appheaders: hostAppHeaders({ nonce, frameOrigins: [process.env.AGENT_ORIGIN!] }) // hostheaders: embeddedAppHeaders({ nonce, hostOrigins: [process.env.BACKOFFICE_ORIGIN!] }) // embedded appInstallation
Once per app, set up Aedis UI. The CLI verifies the signed release before writing anything and pins every dependency:
npx @aedis/cli@0.1.0 initImport the theme once in your global CSS, after Tailwind:
app/globals.css
@import "tailwindcss";@import "./styles/aedis-theme.css";Then add the component:
npx @aedis/cli@0.1.0 add mf-frame# pnpm dlx @aedis/cli@0.1.0 add mf-frame · yarn dlx @aedis/cli@0.1.0 add mf-frame · bunx @aedis/cli@0.1.0 add mf-frameProps
| Prop | Type | Default | Description |
|---|---|---|---|
| src / title | string / string | — | Absolute http(s) URL; title is required. |
| sandbox | SandboxToken[] | ["allow-scripts", "allow-forms"] | Known tokens only; allow-same-origin is refused when the frame has the host's origin. |
| allow / referrerPolicy | string | "" / "strict-origin-when-cross-origin" | Permissions policy (empty: no camera, mic, geolocation…) and referrer. |
| minHeight / maxHeight | number | 120 / 4000 | Bounds for the height the embedded app reports. |
| onBridge / messages | (bridge) => void / specs | — | The mf-bridge to the embedded app, for its own messages. |
| useReportHeight(hostOrigins) | hook | — | In the embedded app: reports the document height to the host. |
| embeddedAppHeaders / hostAppHeaders | lib | — | securityHeaders with frame-ancestors (embedded) or frame-src (host) from configuration. |
Security
- Minimal sandbox; allow-same-origin is refused for a frame on the host's origin, because with allow-scripts it could remove its own sandbox.
- Empty permissions policy, a referrer policy and a required title by default.
- The height comes over mf-bridge from the frame's origin only, and is bounded.
- frame-ancestors on the embedded app and frame-src on the host come from configuration; wildcards and malformed entries are dropped, so neither can become '*'.