open-webui-embeddable-widget
3行HTML让任意网站拥有Open WebUI对话能力,~15KB零依赖
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
3行HTML让任意网站拥有Open WebUI对话能力,~15KB零依赖
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
某公司的售后团队每天要回复大量重复问题,客服不堪重负。产品经理提议接一个 AI 助手,但现有系统是十年前的老系统,改造成本极高。技术团队调研了一圈,要么需要完整的 Node.js 环境,要么需要折腾 OAuth 认证,接入成本让项目胎死腹中。
taylorwilsdon/open-webui-embeddable-widget 正是为这种场景而生:一个不到 15KB 的聊天组件,往页面里一塞,立即拥有 AI 对话能力。 不需要 SPA 框架,不需要 Node.js 服务器,只要你的网站能加载 JS 文件,就能跑起来。
Open WebUI 是目前最受欢迎的开源自托管 AI 对话平台之一,提供了类似 ChatGPT 的完整 Web 界面。但它的野心不止于此——Open WebUI 暴露出标准的 OpenAI 兼容 API(/api/chat/completions),使其可以作为任何 AI 工具的后端。
taylorwilsdon/open-webui-embeddable-widget 正是看准了这个生态位:它不重复造轮子,而是把 Open WebUI 的对话能力以 Widget 形式重新打包,让任何有 Web 页面的场景都能享用。开发者 taylorwilsdon 的设计哲学很清晰——"Dead Simple Integration",三行 HTML 搞定接入。
该 Widget 本质上是一个 Svelte 5 构建的单文件组件,构建产物为 ChatWidget.js(约 15KB)和 owui-widget.css。接入流程极其简单:
<link rel="stylesheet" href="https://your-cdn.com/owui-widget.css">
<div id="chat-widget"></div>
<script type="module">
import ChatWidget, { mount } from 'https://your-cdn.com/ChatWidget.js';
mount(ChatWidget, { target: document.getElementById('chat-widget') });
</script>
三个可配置参数(通过 URL Query String 传入):
| 参数 | 必填 | 说明 |
|---|---|---|
api_key | 是 | Open WebUI 实例的 API Key |
model | 否 | 模型名称,默认 gpt-4o-mini |
endpoint | 否 | 自定义 API 端点,默认 /api/chat/completions |
配置通过 URL 参数传递,意味着不需要修改 HTML,只需在引用页面的 URL 末尾加上参数即可。同一 Widget 文件,不同 URL 参数对应不同模型或不同后端实例。
Widget 界面能力:
marked 库,支持 GFM(GitHub Flavored Markdown),AI 回复中的代码块、表格均可正常显示isLoading 状态控制,发送消息时显示加载指示messages 数组(刷新页面会丢失)代码结构非常扁平:
src/
main.ts # 入口,mount 到 #app
lib/
index.ts # 导出 ChatWidget 和 mount
ChatWidget.svelte # 核心组件
img/ # 预留图片目录(未使用)
ChatWidget.svelte 关键实现(Svelte 5 Runes):
// Svelte 5 响应式状态(Runes 模式)
let messages = $state<{ role: string; content: string }[]>([]);
let input = $state('');
let isLoading = $state(false);
// Side effect: 消息变化时自动滚动
$effect(() => {
if (messages.length && messagesContainer) {
setTimeout(() => {
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}, 100);
}
});
消息发送流程(send 函数):
messagesfetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': f'Bearer {apiKey}' }, body: JSON.stringify({ model, messages }) })choices[0].message 加入 messages注意:API Key 通过 URL 参数传入后存在 JS 变量中,每次请求以 Authorization: Bearer 头发送。但 URL 参数本身仍然可见,这是该方案的安全隐患。
Vite 构建配置(lib 模式):
build: {
lib: {
entry: 'src/lib/index.ts',
formats: ['es'],
fileName: () => 'ChatWidget.js'
}
}
构建产物为纯 ESM 格式的 JS 文件,不包含 Svelte 运行时(Svelte 被打入 bundle),因此是自包含的单一文件,部署简单。
1. API Key 暴露风险(严重)
README 明确警告:"This tool is meant to be extremely simple and is intended for trusted internal user traffic only"。将 API Key 放在 URL 参数中,存在以下风险:
如果需要对外暴露 AI 对话能力,需要在前端再加一层中间代理,由代理服务持有真实 API Key,前端只与代理通信。
2. 消息状态不持久
Widget 将消息存储在内存数组中,页面刷新后全部丢失。对于需要对话历史的场景,需要自行扩展 localStorage 或对接后端存储。
3. 无任何安全加固
Widget 本身没有 CSRF 防护、XSS 过滤、速率限制等安全机制。实际使用时建议配合 WAF 或 API 网关。
4. 无测试覆盖
仓库中没有任何测试文件,代码质量依赖开发者手动验证。
从 Open WebUI 到 AnythingLLM,再到现在的 Embeddable Widget,"把 AI 能力嵌入现有系统" 正在成为 AI 落地的新范式。相比从零搭建 AI 功能,嵌入式方案:
该项目虽然规模不大(121 stars),但在 Open WebUI 生态中填补了一个空白——让"在任意页面加 AI 对话"这件事变得前所未有的简单。随着 Open WebUI 用户群体的扩大,这类 Embeddable Widget 的需求会持续增长。