generative-ui
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGenerative UI
生成式UI
Build generative UI apps with Tambo — create rich, interactive React components from natural language.
使用Tambo构建生成式UI应用——通过自然语言创建丰富的交互式React组件。
Reference Guides
参考指南
For deeper implementation details beyond bootstrap flow, load:
- components
- component-rendering
- threads
- tools-and-context
- cli
These references are duplicated across both skills so each skill works independently.
如需了解引导流程之外的更深入实现细节,请查看:
- components
- component-rendering
- threads
- tools-and-context
- cli
这些参考内容在两个技能中重复提供,以便每个技能都能独立运行。
One-Prompt Flow
单提示流程
The goal is to get the user from zero to a running app in a single prompt. Ask all questions upfront using AskUserQuestion with multiple questions, then execute everything without stopping.
目标是让用户通过一次提示就能从无到有运行起应用。使用AskUserQuestion一次性提出所有问题,然后无需停顿地执行所有操作。
Step 1: Gather All Non-Sensitive Preferences (Single AskUserQuestion Call)
步骤1:收集所有非敏感偏好(单次AskUserQuestion调用)
Use AskUserQuestion with up to 4 questions in ONE call. The API key is collected as free-text input here — no follow-up needed.
Question 1: What do you want to build?
Ask the user what kind of app they're building. This drives which starter components to create. Examples: "a dashboard", "a chatbot", "a data visualization tool", "a task manager". If the user already said what they want in their initial message, skip this question.
Question 2: Framework
Options:
- Next.js (Recommended) - Full-stack React with App Router
- Vite - Fast, lightweight React setup
Question 3: API Key
Do NOT use AskUserQuestion for the API key. Instead, after collecting the other preferences, explicitly ask the user in a plain text message to paste their API key. Say something like:
"Paste your Tambo API key below (get one at https://console.tambo.co). This is a client-side public key (like NEXT_PUBLIC_TAMBO_API_KEY) — not a secret, safe to share here. Or just say 'skip' if you don't have one yet."
Then wait for their response. If they paste a key (starts with ), use it. If they say "skip" or similar, move on without it.
tambo_This means Step 1 only has 3 questions in AskUserQuestion (app idea, framework, app name). The API key is collected as a plain message exchange right after.
Question 4: App name
Let the user pick a name for their project directory. Default suggestion: derive from what they want to build (e.g., "my-dashboard", "my-chatbot"). Use kebab-case (letters, numbers, hyphens only). If the user gives a non-slug name like "Sales Dashboard", propose instead.
sales-dashboardSkip questions when the user already told you the answer. If they said "build me a Next.js dashboard app called analytics", you already know the framework, the app idea, and the name — just ask for the API key.
使用AskUserQuestion在一次调用中提出最多4个问题。API密钥在此处作为纯文本输入收集——无需后续跟进。
问题1:你想要构建什么?
询问用户要构建的应用类型。这将决定要创建哪些初始组件。示例:"一个仪表板"、"一个聊天机器人"、"一个数据可视化工具"、"一个任务管理器"。如果用户在初始消息中已经说明需求,跳过此问题。
问题2:框架选择
选项:
- Next.js(推荐)- 带App Router的全栈React框架
- Vite - 快速、轻量的React开发环境
问题3:API密钥
请勿使用AskUserQuestion获取API密钥。在收集完其他偏好后,用纯文本消息明确要求用户粘贴其API密钥。例如可以说:
"请在下方粘贴你的Tambo API密钥(可在https://console.tambo.co获取)。这是客户端公钥(类似NEXT_PUBLIC_TAMBO_API_KEY)——并非机密信息,可在此安全分享。如果还没有,直接回复'skip'即可。"
然后等待用户回复。如果用户粘贴了密钥(以开头),则使用该密钥。如果用户回复"skip"或类似内容,则跳过此步骤继续后续操作。
tambo_这意味着步骤1中AskUserQuestion仅包含3个问题(应用需求、框架、应用名称)。API密钥在之后通过纯文本消息交互收集。
问题4:应用名称
让用户选择项目目录的名称。默认建议:根据用户的应用需求生成(例如"my-dashboard"、"my-chatbot")。使用短横线分隔格式(仅包含字母、数字和短横线)。如果用户提供的是非短横线格式的名称,如"Sales Dashboard",则建议使用替代。
sales-dashboard如果用户已在初始消息中说明答案,跳过对应问题。如果用户说"帮我构建一个名为analytics的Next.js仪表板应用",那么你已经知道框架、应用需求和名称——只需询问API密钥即可。
Step 2: Execute Everything (No Stopping)
步骤2:执行所有操作(无需停顿)
Run all of these sequentially without asking for confirmation between steps. If any command fails, stop the flow, surface the error, and ask the user how to proceed — do not continue to later steps.
All templates (, , ) come with chat UI, TamboProvider wiring, component registry, and starter components already included. You do NOT need to add chat UI or wire up the app — just scaffold, configure the API key, add custom components, and start the server.
standardviteanalytics按顺序运行以下所有操作,步骤之间无需确认。如果任何命令失败,停止流程,显示错误信息,并询问用户如何处理——不要继续后续步骤。
所有模板(、、)都已包含聊天UI、TamboProvider配置、组件注册表和初始组件。你无需添加聊天UI或配置应用——只需搭建项目、配置API密钥、添加自定义组件并启动服务器。
standardviteanalytics2a. Scaffold the project
2a. 搭建项目框架
For Next.js (recommended):
bash
npx tambo create-app <app-name> --template=standard --skip-tambo-init
cd <app-name>For Vite:
bash
npx tambo create-app <app-name> --template=vite --skip-tambo-init
cd <app-name>Use since normally tries to run interactively, which won't work in non-interactive environments like coding agents. We handle the API key in the next step.
--skip-tambo-initcreate-apptambo init对于Next.js(推荐):
bash
npx tambo create-app <app-name> --template=standard --skip-tambo-init
cd <app-name>对于Vite:
bash
npx tambo create-app <app-name> --template=vite --skip-tambo-init
cd <app-name>使用参数,因为通常会尝试交互式运行,这在编码代理等非交互式环境中无法正常工作。我们将在下一步处理API密钥配置。
--skip-tambo-initcreate-apptambo init2b. Set up API key
2b. 设置API密钥
If the user provided a key:
bash
npx tambo init --api-key=<USER_PROVIDED_KEY>This writes the key to the correct file with the framework-appropriate variable name (, , etc.).
.envNEXT_PUBLIC_TAMBO_API_KEYVITE_TAMBO_API_KEYIf the user skipped, tell them once at the end to run when ready. Don't nag about it during setup.
npx tambo initIMPORTANT: Do NOT hardcode in commands you run. The flag should only be used with an actual key the user has provided.
--api-key=sk_...--api-key如果用户提供了密钥:
bash
npx tambo init --api-key=<USER_PROVIDED_KEY>这会将密钥写入正确的文件,并使用适合对应框架的变量名(、等)。
.envNEXT_PUBLIC_TAMBO_API_KEYVITE_TAMBO_API_KEY如果用户跳过了密钥设置,在流程结束时提醒他们一次,待准备好后运行即可。在设置过程中不要反复提及此事。
npx tambo init重要提示: 请勿在运行的命令中硬编码。标志仅应与用户提供的实际密钥一起使用。
--api-key=sk_...--api-key2c. Create custom starter components
2c. 创建自定义初始组件
The template includes basic components, but add 1-2 components tailored to what the user wants to build. Don't use generic examples:
- Dashboard app → ,
StatsCardDataTable - Chatbot → with markdown support
BotResponse - Data visualization → with configurable data
Chart - Task manager → ,
TaskCardTaskBoard - Generic / unclear →
ContentCard
Each component needs:
- A Zod schema with on every field
.describe() - The React component itself
- Registration in the existing component registry (— add to the existing
lib/tambo.tsarray, don't replace it)components
Schema constraints — Tambo will reject invalid schemas at runtime:
- No — Record types (objects with dynamic keys) are not supported anywhere in the schema, including nested inside arrays or objects. Use
z.record()with explicit named keys instead.z.object() - No or
z.map()— Use arrays and objects instead.z.set() - For tabular data like rows, use with explicit column keys — NOT
z.array(z.object({ col1: z.string(), col2: z.number() })).z.array(z.record(z.string(), z.unknown()))
React best practices for generated components:
- Always add unique props when rendering lists (
key). Use a unique field from the data (like.map()) — not the array index.id - Include an field (e.g.,
id) in schemas for array items so there's always a stable key available.z.string().describe("Unique identifier")
Example:
tsx
// src/components/StatsCard.tsx
import { z } from "zod/v4";
export const StatsCardSchema = z.object({
title: z.string().describe("Metric name"),
value: z.number().describe("Current value"),
change: z.number().optional().describe("Percent change from previous period"),
trend: z.enum(["up", "down", "flat"]).optional().describe("Trend direction"),
});
type StatsCardProps = z.infer<typeof StatsCardSchema>;
export function StatsCard({
title,
value,
change,
trend = "flat",
}: StatsCardProps) {
// ... implementation with Tailwind styling
}Then add to the existing registry in :
lib/tambo.tstsx
// Add to the existing components array — don't replace what's already there
// Next.js: import { StatsCard, StatsCardSchema } from "@/components/StatsCard";
// Vite: import { StatsCard, StatsCardSchema } from "../components/StatsCard";
import { StatsCard, StatsCardSchema } from "@/components/StatsCard";
// ... existing components ...
{
name: "StatsCard",
component: StatsCard,
description: "Displays a metric with value and trend. Use when user asks about stats, metrics, or KPIs.",
propsSchema: StatsCardSchema,
},模板中包含基础组件,但需添加1-2个符合用户需求的定制组件。请勿使用通用示例:
- 仪表板应用 → 、
StatsCardDataTable - 聊天机器人 → 支持markdown的
BotResponse - 数据可视化工具 → 可配置数据的
Chart - 任务管理器 → 、
TaskCardTaskBoard - 通用/需求不明确 →
ContentCard
每个组件需要包含:
- 每个字段都带有的Zod schema
.describe() - React组件本身
- 在现有组件注册表中注册(——添加到现有的
lib/tambo.ts数组中,不要替换原有内容)components
Schema约束——Tambo在运行时会拒绝无效的schema:
- 禁止使用——记录类型(带有动态键的对象)在schema的任何位置都不被支持,包括数组或对象内部。请改用带有明确命名键的
z.record()。z.object() - 禁止使用或
z.map()——请改用数组和对象。z.set() - 对于表格数据(如行),请使用并带有明确的列键——不要使用
z.array(z.object({ col1: z.string(), col2: z.number() }))。z.array(z.record(z.string(), z.unknown()))
生成组件的React最佳实践:
- 渲染列表()时始终添加唯一的
.map()属性。使用数据中的唯一字段(如key)——不要使用数组索引。id - 在数组项的schema中包含字段(例如
id),以便始终有稳定的key可用。z.string().describe("唯一标识符")
示例:
tsx
// src/components/StatsCard.tsx
import { z } from "zod/v4";
export const StatsCardSchema = z.object({
title: z.string().describe("指标名称"),
value: z.number().describe("当前数值"),
change: z.number().optional().describe("与上期相比的变化百分比"),
trend: z.enum(["up", "down", "flat"]).optional().describe("趋势方向"),
});
type StatsCardProps = z.infer<typeof StatsCardSchema>;
export function StatsCard({
title,
value,
change,
trend = "flat",
}: StatsCardProps) {
// ... 使用Tailwind样式的实现代码
}然后添加到中的现有注册表:
lib/tambo.tstsx
// 添加到现有的components数组中——不要替换原有内容
// Next.js: import { StatsCard, StatsCardSchema } from "@/components/StatsCard";
// Vite: import { StatsCard, StatsCardSchema } from "../components/StatsCard";
import { StatsCard, StatsCardSchema } from "@/components/StatsCard";
// ... 现有组件 ...
{
name: "StatsCard",
component: StatsCard,
description: "显示带有数值和趋势的指标。当用户询问统计数据、指标或KPI时使用。",
propsSchema: StatsCardSchema,
},2d. Start the dev server
2d. 启动开发服务器
Only start the dev server after all code changes (scaffolding, init, component creation, registry updates) are complete.
bash
npm run devRun this in the background so the user can see their app immediately.
仅在所有代码变更(项目搭建、初始化、组件创建、注册表更新)完成后启动开发服务器。
bash
npm run dev在后台运行此命令,以便用户能立即看到他们的应用。
Step 3: Summary
步骤3:总结
After everything is running, give a brief summary:
- What was set up
- What components were created and what they do
- The URL where the app is running (typically for Next.js,
http://localhost:3000for Vite)http://localhost:5173 - If they skipped the API key: remind them once to run to set it up
npx tambo init - A suggestion for what to try first (e.g., "Try asking it to show you a stats card for monthly revenue")
所有操作完成后,提供简要总结:
- 已搭建的内容
- 创建的组件及其功能
- 应用运行的URL(Next.js通常为,Vite通常为
http://localhost:3000)http://localhost:5173 - 如果用户跳过了API密钥设置:提醒他们一次,待准备好后运行进行配置
npx tambo init - 首次尝试的建议(例如:"尝试让它展示月度收入的统计卡片")
Technology Stacks Reference
技术栈参考
Recommended Stack (Default)
推荐技术栈(默认)
Next.js 14+ (App Router)
├── TypeScript
├── Tailwind CSS
├── Zod (for schemas)
└── @tambo-ai/reactbash
npx tambo create-app my-app --template=standardNext.js 14+ (App Router)
├── TypeScript
├── Tailwind CSS
├── Zod(用于schema)
└── @tambo-ai/reactbash
npx tambo create-app my-app --template=standardVite Stack
Vite技术栈
Vite + React
├── TypeScript
├── Tailwind CSS
├── Zod
└── @tambo-ai/reactVite + React
├── TypeScript
├── Tailwind CSS
├── Zod
└── @tambo-ai/reactMinimal Stack (No Tailwind)
极简技术栈(无Tailwind)
Vite + React
├── TypeScript
├── Plain CSS
├── Zod
└── @tambo-ai/reactVite + React
├── TypeScript
├── 纯CSS
├── Zod
└── @tambo-ai/reactComponent Registry Pattern
组件注册表模式
Every generative component must be registered:
tsx
import { TamboComponent } from "@tambo-ai/react";
import { ComponentName, ComponentNameSchema } from "@/components/ComponentName";
export const components: TamboComponent[] = [
{
name: "ComponentName",
component: ComponentName,
description: "What it does. When to use it.",
propsSchema: ComponentNameSchema,
},
];Key rules:
- propsSchema: Zod object with on every field — this is how the AI knows what to pass
.describe() - description: Tell the AI when to use this component — be specific about trigger phrases
- Streaming: Props arrive incrementally, so handle undefined gracefully (optional fields or defaults)
每个生成式组件都必须注册:
tsx
import { TamboComponent } from "@tambo-ai/react";
import { ComponentName, ComponentNameSchema } from "@/components/ComponentName";
export const components: TamboComponent[] = [
{
name: "ComponentName",
component: ComponentName,
description: "组件功能及使用场景。",
propsSchema: ComponentNameSchema,
},
];核心规则:
- propsSchema:每个字段都带有的Zod对象——AI通过此了解需要传递的参数
.describe() - description:告知AI何时使用该组件——明确说明触发短语
- 流式传输:参数会增量传递,因此需优雅处理未定义的情况(可选字段或默认值)
Adding More Chat UI (Optional)
添加更多聊天UI(可选)
Templates already include chat UI. These are only needed if the user wants additional UI primitives beyond what the template provides:
bash
npx tambo add message-thread-full --yes # Complete chat interface
npx tambo add control-bar --yes # Controls and actions
npx tambo add canvas-space --yes # Rendered component display area
npx tambo add thread-history --yes # Conversation history sidebar模板中已包含聊天UI。仅当用户需要模板之外的额外UI原语时,才需要使用以下命令:
bash
npx tambo add message-thread-full --yes # 完整的聊天界面
npx tambo add control-bar --yes # 控制栏及操作按钮
npx tambo add canvas-space --yes # 渲染组件的展示区域
npx tambo add thread-history --yes # 对话历史侧边栏Supported Technologies
支持的技术
| Technology | Support Level | Notes |
|---|---|---|
| Next.js 14+ | Full | Recommended, App Router preferred |
| Vite | Full | Great for SPAs |
| Create React App | Partial | Works but CRA is deprecated |
| Remix | Partial | Works with client components |
| TypeScript | Full | Strongly recommended |
| JavaScript | Full | Works but less type safety |
| Tailwind CSS | Full | Default for CLI components |
| Plain CSS | Full | Need custom component styling |
| CSS Modules | Full | Supported |
| Zod | Required | Used for all schemas |
| 技术 | 支持等级 | 说明 |
|---|---|---|
| Next.js 14+ | 完全支持 | 推荐使用,优先选择App Router |
| Vite | 完全支持 | 非常适合单页应用 |
| Create React App | 部分支持 | 可运行但CRA已被弃用 |
| Remix | 部分支持 | 可与客户端组件配合使用 |
| TypeScript | 完全支持 | 强烈推荐 |
| JavaScript | 完全支持 | 可运行但类型安全性较低 |
| Tailwind CSS | 完全支持 | CLI组件的默认样式方案 |
| 纯CSS | 完全支持 | 需要自定义组件样式 |
| CSS Modules | 完全支持 | 已兼容 |
| Zod | 必须使用 | 所有schema均依赖此库 |
| ", |