You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BotFramework-WebChat在Shadow DOM中渲染时样式失效的问题排查与求助

BotFramework-WebChat在Shadow DOM中渲染时样式失效的问题排查与求助

我最近需要把BotFramework-WebChat嵌入到现有网站中,但为了避免WebChat的CSS样式泄露到主网站,或者主网站的样式影响WebChat,打算把它渲染到Shadow DOM里。

我查了相关的资料,GitHub上的Issue #5194提到了这个需求,而且PR #5196已经实现了Shadow DOM的支持,但官方并没有给出具体的使用教程。我尝试从PR里的单元测试代码去推断实现方式,但折腾了很久,WebChat始终没法正确渲染——组件能出来,但所有BotFramework自带的样式都不生效,完全是裸的HTML结构。

以下是我尝试实现的TypeScript核心代码:

export const startChat = async (serviceName: string, clientId?: string): Promise<void> => {
  const user = await requestToken(serviceName);
  if (user === null) return;

  webchatState.user = user;
  initializeDirectLine();

  const shadowRoot = document.body.attachShadow({ mode: "open" });
  const container = document.createElement("div");
  container.id = "webchat";
  shadowRoot.appendChild(container);

  const styleOptions: WebChat.IStyleOptions = {
    avatarBorderRadius: "50%",
    avatarSize: 40,
    botAvatarBackground: getCssVariableValue("--secondary"),
    botAvatarBackgroundColor: getCssVariableValue("--secondary"),
    botAvatarImage: chatbotAvatarImg,
    botAvatarInitials: "",
    bubbleBackground: getCssVariableValue("--primary"),
    bubbleBorderRadius: "15px",
    bubbleBorderStyle: "solid",
    bubbleBorderWidth: 1,
    bubbleFromUserBackground: getCssVariableValue("--secondary"),
    bubbleFromUserBorderColor: getCssVariableValue("--primary"),
    bubbleFromUserBorderRadius: "15px",
    bubbleFromUserBorderStyle: "solid",
    bubbleFromUserBorderWidth: 1,
    bubbleFromUserTextColor: getCssVariableValue("--text-secondary"),
    bubbleTextColor: getCssVariableValue("--secondary"),
    hideUploadButton: true,
    sendBoxBackground: "White",
    sendBoxBorderBottom: "",
    sendBoxBorderLeft: "",
    sendBoxBorderRight: "",
    sendBoxBorderTop: `solid 1px ${getCssVariableValue("--primary")}`,
    sendBoxButtonColor: getCssVariableValue("--primary"),
    sendBoxHeight: 40,
    sendBoxTextColor: "Black",
    stylesRoot: shadowRoot,
    userAvatarBackgroundColor: getCssVariableValue("--secondary"),
    userAvatarImage: userAvatarImg,
    userAvatarInitials: "",
  };

  if (container !== null) {
    window.WebChat.renderWebChat(
      {
        directLine: webchatState.directLine,
        userID: webchatState.user.id,
        styleOptions,
      },
      container
    );
  }
  await sendClientIdActivity(clientId);
  await sendRequestWelcomeMessage();
  await sendStartBot();
};

后来我调整了Shadow DOM容器的创建方式,改成这样:

const webchatHost = document.createElement("div");
webchatHost.id = "webchat-host";

const shadowRoot = webchatHost.attachShadow({ mode: "open" });

const webChatContainer = document.createElement("div");
webChatContainer.id = "webchat-container";
webChatContainer.style.height = "200px";
webChatContainer.style.width = "100%";

shadowRoot.appendChild(webChatContainer);

document.body.appendChild(webchatHost);

调整后,WebChat的容器有了高度和宽度,但样式还是没生效——界面就是一堆无样式的文本和输入框,完全没有BotFramework默认的聊天窗口样式。而如果我不使用Shadow DOM,直接渲染到普通div里,WebChat就能正常显示所有样式,完全没问题。

我已经排查了这些点:

  • 获取用户令牌、初始化DirectLine的流程都正常,能成功和Bot建立连接
  • 引用的BotFramework-WebChat CDN是最新版本
  • StyleOptions里的stylesRoot参数已经正确传入了Shadow DOM的根节点,类型也符合定义
  • 参考了GitHub Issue #5315里的实现方式,但还是同样的问题
  • 确认不是DirectLine的问题,因为非Shadow DOM环境下完全正常

附我定义的IStyleOptions类型(和BotFramework仓库里的类型一致):

interface IStyleOptions {
    [index: string]: number | string | boolean | Node;
    avatarBorderRadius: string;
    avatarSize: number;
    botAvatarBackground: string;
    botAvatarBackgroundColor: string;
    botAvatarImage: string;
    botAvatarInitials: string;
    bubbleBackground: string;
    bubbleBorderRadius: string;
    bubbleBorderStyle: string;
    bubbleBorderWidth: number;
    bubbleFromUserBackground: string;
    bubbleFromUserBorderColor: string;
    bubbleFromUserBorderRadius: string;
    bubbleFromUserBorderStyle: string;
    bubbleFromUserBorderWidth: number;
    bubbleFromUserTextColor: string;
    bubbleTextColor: string;
    hideUploadButton: boolean;
    sendBoxBackground: string;
    sendBoxBorderBottom: string;
    sendBoxBorderLeft: string;
    sendBoxBorderRight: string;
    sendBoxBorderTop: string;
    sendBoxButtonColor: string;
    sendBoxHeight: number;
    sendBoxTextColor: string;
    stylesRoot: Node;
    userAvatarBackgroundColor: string;
    userAvatarImage: string;
    userAvatarInitials: string;
  }

有没有大佬成功在Shadow DOM里渲染过BotFramework-WebChat并且样式正常的?麻烦帮忙看看我的代码哪里有问题,或者有没有正确的实现步骤可以参考?

备注:内容来源于stack exchange,提问作者Dirk Odendaal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 15:48:04