# Chat UI 链接渲染问题修复报告
## 📝 问题描述
用户报告Chat UI上的链接没有正确被渲染,从截图中可以看到:
- 内容中包含HTML格式的``标签而不是markdown格式的链接
- 链接文本显示但不可点击
- HTML代码直接显示在UI中
## 🔍 根本原因分析
1. **组件配置冲突**:
- `MyChat`组件同时配置了`assistantMessage: { components: { Text: MarkdownText } }`
- 又使用了自定义的`AiAssistantMessage`组件
- `AiAssistantMessage`使用默认的``,忽略了MarkdownText配置
2. **Agent输出格式问题**:
- Agent生成HTML格式的链接而不是Markdown格式
- 后端citations处理正确生成Markdown,但Agent本身输出了HTML
3. **前端处理能力不足**:
- `MarkdownTextPrimitive`只能处理markdown,不能处理HTML
- 缺少`@tailwindcss/typography`插件支持prose样式
- 没有DOMPurify来安全处理HTML内容
## ✅ 解决方案
### 1. 修复组件配置冲突
```tsx
// AiAssistantMessage.tsx - 直接指定MarkdownText组件
// mychat.tsx - 移除重复配置
config={{
welcome: { message: t.welcomeMessage },
// 移除了 assistantMessage 配置
}}
```
### 2. 增强MarkdownText组件
```tsx
// 智能检测内容类型并相应处理
const containsHTMLLinks = typeof content === 'string' && /]*href/i.test(content);
if (containsHTMLLinks) {
// HTML内容:使用DOMPurify清理后直接渲染
return ;
} else {
// Markdown内容:使用标准的markdown处理器
return ;
}
```
### 3. 添加必要的依赖
```bash
pnpm add @tailwindcss/typography # Prose样式支持
pnpm add isomorphic-dompurify # 安全HTML清理
pnpm add rehype-external-links # 外部链接处理
```
### 4. 更新Agent系统提示
```yaml
agent_system_prompt: |
# Response Format Requirements:
- Use ONLY Markdown formatting (headers, lists, emphasis, etc.)
- DO NOT use HTML tags like , , etc. Use only Markdown link syntax
- DO NOT generate HTML anchor tags - the system will convert markdown links automatically
```
### 5. 增强Tailwind配置
```typescript
// tailwind.config.ts
plugins: [
require("tailwindcss-animate"),
require("@tailwindcss/typography"), // 新增
require("@assistant-ui/react-ui/tailwindcss")({...})
],
```
## 🎯 修复效果
现在Chat UI应该能够:
1. ✅ **正确渲染链接**:无论是Markdown还是HTML格式
2. ✅ **安全处理**:DOMPurify清理恶意HTML内容
3. ✅ **外部链接安全**:自动添加`target="_blank"`和`rel="noopener noreferrer"`
4. ✅ **视觉样式**:链接显示为蓝色,有适当的悬停效果
5. ✅ **保持功能**:typing indicator等现有功能不受影响
## 🔧 技术实现细节
### 智能内容检测
```typescript
const containsHTMLLinks = /]*href/i.test(content);
```
### HTML属性确保
```typescript
processedContent = processedContent.replace(
/]*?)href\s*=\s*["']([^"']+)["']([^>]*?)>/gi,
(match, before, href, after) => {
const isExternal = href.startsWith('http://') || href.startsWith('https://');
if (isExternal) {
// 确保安全属性存在
let attributes = before + after;
if (!attributes.includes('target=')) attributes += ' target="_blank"';
if (!attributes.includes('rel=')) attributes += ' rel="noopener noreferrer"';
return ``;
}
return match;
}
);
```
### DOMPurify安全清理
```typescript
const sanitizedHTML = DOMPurify.sanitize(processedContent, {
ALLOWED_TAGS: ['a', 'p', 'div', 'span', 'strong', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'br'],
ALLOWED_ATTR: ['href', 'target', 'rel', 'title', 'class']
});
```
## 📋 测试验证
1. **服务器状态**:✅ 后端服务运行在 http://127.0.0.1:8000
2. **前端状态**:✅ 前端开发服务器运行在 http://localhost:3001
3. **构建测试**:✅ 所有组件正常构建
4. **依赖完整**:✅ 所有必要的npm包已安装
## 🔮 下一步
1. 在浏览器中访问 http://localhost:3001 测试Chat UI
2. 发送包含引用的查询验证链接渲染
3. 检查链接是否可点击且在新标签页打开
4. 验证typing indicator等功能正常工作
这个解决方案提供了向后兼容性,能够处理两种内容格式,并确保了安全性和用户体验。