6.4 KiB
6.4 KiB
公开页 · iframe 嵌入外观对接说明(主题 / 背景色)
本文档面向嵌入方(宿主系统),说明如何在用 <iframe> 嵌入 DeerFlow 公开页时,从外部控制页面的整体明暗主题(light/dark)与背景色 / 文字色,使其与宿主站点的视觉风格保持一致。
前端实现见:src/core/embed/background.ts(参数解析与 postMessage 监听)、src/App.tsx(主题接入 forcedTheme)。
0. 速读
| 想做什么 | 怎么做 |
|---|---|
| 嵌入时指定深色主题 | iframe src 加 ?theme=dark |
| 嵌入时指定背景/文字色 | iframe src 加 ?bg=%23001529&text=%23ffffff(# 需编码为 %23) |
| 宿主切主题时同步切换 | postMessage({ type: "deerflow:set-theme", theme: "dark" }, "*") |
| 宿主动态改背景色 | postMessage({ type: "deerflow:set-bg", bg: "#001529", text: "#fff" }, "*") |
| 什么都不传 | 页面使用 DeerFlow 自带默认配色,互不影响 |
1. 适用页面
以下公开页(免登录、只读)均支持本文档的全部参数:
| 页面 | 路由 |
|---|---|
| 会话分享页 | /#/share/{shareCode} |
| 圆桌分享页 | /#/roundtable-share/{shareCode}、/#/roundtable-share/{shareCode}/report |
| 用户排行榜 | /#/public/leaderboard |
| 定时任务公开页 | /#/public/scheduled-tasks/{taskId}(含 /runs/{runId}/fullscreen 全屏页) |
注意:站点使用 hash 路由,路径在
#之后。 嵌入聊天页(/#/embed/chats/*、/#/embed/roundtable)有自己的主题约定,见embed-iframe-chat.md,不在本文范围内。
2. URL 查询参数(嵌入时一次性指定)
2.1 参数列表
| 参数 | 别名 | 作用 | 合法值 |
|---|---|---|---|
theme |
— | 切整体明暗主题 | 见 2.2 取值映射表 |
bg |
background |
页面根容器背景色 | 见 2.3 颜色格式 |
text |
fg |
页面根容器文字色 | 见 2.3 颜色格式 |
三个参数相互独立,可任意组合;不传或传非法值时该项忽略、沿用默认。
2.2 theme 取值映射
| 传入值(不区分大小写) | 实际主题 |
|---|---|
dark、dark-blue、深蓝、深色 |
深色 |
light、red、红白、浅色 |
浅色 |
| 其他 / 不传 | 忽略,沿用站内默认(浅色) |
2.3 颜色格式(bg / text)
颜色值经过白名单校验,仅接受以下写法,其余一律丢弃(防注入):
- hex:
#fff、#ffffffcc等 3/4/6/8 位(#可省略;URL 里#必须编码为%23) - 函数式:
rgb()/rgba()/hsl()/hsla(),括号内仅允许数字、逗号、百分号、空格、/ - 命名色:纯英文字母,如
white、transparent
2.4 参数位置
参数放在 hash 路由之后(推荐)或 # 之前都能识别;两处都传时hash 路由内的优先:
https://<host>/#/public/leaderboard?theme=dark ← 推荐
https://<host>/?theme=dark#/public/leaderboard ← 也支持
2.5 示例
<!-- 深色主题 -->
<iframe src="https://<host>/#/public/leaderboard?theme=dark"></iframe>
<!-- 浅色主题 + 自定义背景与文字色(# 编码为 %23) -->
<iframe src="https://<host>/#/share/Ab3xYz?theme=light&bg=%23f5f7fa&text=%23333333"></iframe>
<!-- 主题与背景叠加:整页走深色变量,根背景用宿主品牌色 -->
<iframe src="https://<host>/#/roundtable-share/Ab3xYz?theme=dark&bg=%23001529"></iframe>
3. postMessage(嵌入后动态切换)
适用于宿主站点支持用户切主题、需要 iframe 实时跟随的场景。向 iframe 的 contentWindow 发消息即可,无需等待子页面回执(监听器在应用挂载时注册)。
3.1 消息格式
const frame = document.getElementById("deerflow-frame");
// 切整体明暗主题(theme 取值同 2.2)
frame.contentWindow.postMessage({ type: "deerflow:set-theme", theme: "dark" }, "*");
// 改背景色 / 文字色(字段名与 URL 参数一致,bg/background、text/fg 均可)
frame.contentWindow.postMessage({ type: "deerflow:set-bg", bg: "#001529", text: "#fff" }, "*");
// 兼容别名:type 也可写 "deerflow:set-background"
说明:
- 两类消息相互独立,可只发其一;
set-bg里bg、text也可只传其一,未传的字段保持当前值。 - 非法颜色值 / 不认识的
theme取值会被忽略,不会清空已有设置。 - targetOrigin 建议按需收紧(写 DeerFlow 站点的 origin 而非
"*")。
3.2 宿主主题联动示例
function syncDeerflowTheme(isDark) {
const win = document.getElementById("deerflow-frame").contentWindow;
win.postMessage({ type: "deerflow:set-theme", theme: isDark ? "dark" : "light" }, "*");
win.postMessage(
{ type: "deerflow:set-bg", bg: isDark ? "#001529" : "#ffffff" },
"*",
);
}
// iframe 首次加载用 URL 参数兜底,之后切换走 postMessage
myThemeStore.subscribe((theme) => syncDeerflowTheme(theme === "dark"));
4. 优先级与默认行为
同一项配置多处传入时,按以下优先级取值(高 → 低):
- postMessage 动态设置的值
- hash 路由内的 URL 参数(
#/路由?theme=...) #之前的 URL 参数(?theme=...#/路由)- 都没传 → DeerFlow 默认配色(浅色主题 + 页面自带 Tailwind 配色)
其他保证:
- 外部主题只影响当前 iframe 的渲染,不写 localStorage——不会污染用户直接访问 DeerFlow 主站时自己选择的主题。
bg/text是内联样式,作用在页面根容器上,优先级高于主题变量;与theme叠加时以bg/text为准。
5. 常见问题排查
| 现象 | 排查 |
|---|---|
theme=dark 不生效 |
确认路由属于第 1 节列出的公开页;确认参数拼在 hash 路由后(/#/share/xx?theme=dark),而不是写成了 /#/share/xx#theme=dark |
bg=#fff 不生效 |
URL 里 # 没编码会被浏览器截断,必须写 %23fff;或直接省略 # 写 bg=fff |
| postMessage 无反应 | 确认消息体是对象且 type 拼写为 deerflow:set-theme / deerflow:set-bg;确认在 iframe load 之后发送 |
| 颜色被忽略 | 检查是否符合 2.3 白名单格式(如 linear-gradient(...) 等复杂值不支持) |
| 主题切了但个别区域颜色没变 | 该区域可能使用了固定配色;把页面路由与截图反馈给 DeerFlow 维护方补充 dark: 样式 |