现象
#1294 spec 用 embeddable: boolean + allowedEmbedOrigins: string[] 表达嵌入,但实际嵌入有两种截然不同的模式:
- 整页 iframe — 客户官网
/help 路径整页嵌入 portal(少见)
- Widget(聊天泡泡) — 右下角悬浮按钮,点击展开(99% 的 helpdesk/客服真实用法:Intercom、Zendesk Web Widget、Drift 全用这种)
当前 spec 表达不出 widget 的具体形态。
复现
- 客户希望在他官网右下角放一个紫色聊天按钮
- 点击展开后浮出 portal 内容(不占整页)
- spec 只能说
embeddable: true,没法声明 trigger、位置、launcher icon
分阶段建议
M3:把 embeddable 替换为 discriminated embed:
embed?: {
mode: 'iframe';
allowedOrigins: string[];
} | {
mode: 'widget';
allowedOrigins: string[];
launcher: {
position: 'bottom-right'|'bottom-left'|'top-right'|'top-left';
offset?: { x: number; y: number };
iconUrl?: string; // 默认聊天泡泡
label?: I18nLabel; // 折叠时显示文本,如「需要帮助?」
backgroundColor?: string; // 默认继承 portal.theme.primaryColor
};
panel: {
width: number; // px
height: number; // px
openOnInit?: boolean;
showHeader?: boolean;
};
// 嵌入脚本由 framework 生成:
// <script src="/embed/<portal_id>.js" async></script>
}
运行时 framework 生成 /embed/<portal_id>.js 静态脚本,业务方一行 script 接入。
验收
- 模板声明 widget mode → 输出
<script src="/embed/helpdesk_customer.js">
- 嵌入页面右下角出现按钮,点击展开 portal
- CSP
frame-ancestors 正确限制 origins
关联
现象
#1294 spec 用
embeddable: boolean + allowedEmbedOrigins: string[]表达嵌入,但实际嵌入有两种截然不同的模式:/help路径整页嵌入 portal(少见)当前 spec 表达不出 widget 的具体形态。
复现
embeddable: true,没法声明 trigger、位置、launcher icon分阶段建议
M3:把
embeddable替换为 discriminatedembed:运行时 framework 生成
/embed/<portal_id>.js静态脚本,业务方一行 script 接入。验收
<script src="/embed/helpdesk_customer.js">frame-ancestors正确限制 origins关联