- 手风琴 (Accordion)
- 警示框 (Alert)
- 对话框 (Alert Dialog)
- 宽高比 (Aspect Ratio)
- 头像 (Avatar)
- 徽章 (Badge)
- 面包屑 (Breadcrumb)
- 按钮 (Button)
- 按钮组 (Button Group)
- 日历 (Calendar)
- 卡片 (Card)
- 轮播 (Carousel)
- 图表 (Chart)
- 复选框 (Checkbox)
- 折叠面板 (Collapsible)
- 组合框 (Combobox)
- 命令栏 (Command)
- 上下文菜单 (Context Menu)
- 数据表格 (Data Table)
- 日期选择器 (Date Picker)
- 对话框 (Dialog)
- 方向 (Direction)
- 抽屉 (Drawer)
- 下拉菜单 (Dropdown Menu)
- 空状态 (Empty)
- 字段 (Field)
- 悬浮卡片 (Hover Card)
- 输入框 (Input)
- 输入框组 (Input Group)
- OTP 输入框 (Input OTP)
- 项目 (Item)
- 快捷键 (Kbd)
- 标签 (Label)
- 菜单栏 (Menubar)
- 原生选择框 (Native Select)
- 导航菜单 (Navigation Menu)
- 分页 (Pagination)
- 气泡卡片 (Popover)
- 进度条 (Progress)
- 单选组 (Radio Group)
- 可调节大小 (Resizable)
- 滚动区域 (Scroll Area)
- 选择框 (Select)
- 分隔线 (Separator)
- 侧边栏 (Sheet)
- 导航侧边栏 (Sidebar)
- 骨架屏 (Skeleton)
- 滑块 (Slider)
- Sonner (吐司通知)
- 加载器 (Spinner)
- 开关 (Switch)
- 表格 (Table)
- 标签页 (Tabs)
- 文本域 (Textarea)
- 吐司 (Toast)
- 切换按钮 (Toggle)
- 切换组 (Toggle Group)
- 文字提示 (Tooltip)
- 排版 (Typography)
带命名空间的注册表允许你在一个项目中配置多个资源来源。这意味着你可以从各种注册表安装组件、库、工具、AI 提示词、配置文件和其他资源,无论是公共的、第三方的还是你自定义的私有库。
目录
概览
注册表命名空间以 @ 为前缀,提供了一种组织和引用不同来源资源的方法。资源可以是任何类型的内容:组件、库、工具、钩子 (hooks)、AI 提示词、配置文件、主题等。例如:
@shadcn/button- 来自 shadcn 注册表的 UI 组件@v0/dashboard- 来自 v0 注册表的仪表盘组件@ai-elements/input- 来自 AI 元素注册表的 AI 提示词输入@acme/auth-utils- 来自你公司私有注册表的认证工具@ai/chatbot-rules- 来自 AI 资源注册表的 AI 提示词规则@themes/dark-mode- 来自主题注册表的主题配置
去中心化命名空间系统
我们刻意将命名空间系统设计为去中心化的。虽然有一个集中的开源注册表索引用于开源命名空间,但你可以自由创建和使用任何你想要的命名空间。
这种去中心化的方法为你提供了完全的灵活性,可以根据对你组织有意义的方式来组织资源。
你可以为不同目的创建多个注册表:
{
"registries": {
"@acme-ui": "https://registry.acme.com/ui/{name}.json",
"@acme-docs": "https://registry.acme.com/docs/{name}.json",
"@acme-ai": "https://registry.acme.com/ai/{name}.json",
"@acme-themes": "https://registry.acme.com/themes/{name}.json",
"@acme-internal": {
"url": "https://internal.acme.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${INTERNAL_TOKEN}"
}
}
}
}这使你能够:
- 按类型组织:分离 UI 组件、文档、AI 资源等。
- 按团队组织:不同的团队可以维护他们自己的注册表。
- 按可见性组织:公共资源与私有资源。
- 按版本组织:稳定版与实验版注册表。
- 无命名冲突:由于没有中央权威,你不必担心命名空间冲突。
多注册表设置示例
按资源类型
{
"@components": "https://cdn.company.com/components/{name}.json",
"@hooks": "https://cdn.company.com/hooks/{name}.json",
"@utils": "https://cdn.company.com/utils/{name}.json",
"@prompts": "https://cdn.company.com/ai-prompts/{name}.json"
}按团队或部门
{
"@design": "https://create.company.com/registry/{name}.json",
"@engineering": "https://eng.company.com/registry/{name}.json",
"@marketing": "https://marketing.company.com/registry/{name}.json"
}按稳定性
{
"@stable": "https://registry.company.com/stable/{name}.json",
"@latest": "https://registry.company.com/beta/{name}.json",
"@experimental": "https://registry.company.com/experimental/{name}.json"
}入门
安装资源
配置完成后,你可以使用命名空间语法安装资源:
pnpm dlx shadcn@latest add @v0/dashboard
或一次性安装多个资源:
pnpm dlx shadcn@latest add @acme/header @lib/auth-utils @ai/chatbot-rules
快速配置
将注册表添加到你的 components.json 文件中:
{
"registries": {
"@v0": "https://v0.dev/chat/b/{name}",
"@acme": "https://registry.acme.com/resources/{name}.json"
}
}然后开始安装:
pnpm dlx shadcn@latest add @acme/button
注册表命名规范
注册表名称必须遵循以下规则:
- 以
@符号开头 - 只能包含字母数字字符、连字符和下划线
- 有效名称示例:
@v0,@acme-ui,@my_company
引用资源的模式为:@namespace/resource-name
配置
带命名空间的注册表是在你的 components.json 文件中的 registries 字段下进行配置的。
基本配置
配置注册表的最简单方法是使用 URL 模板字符串:
{
"registries": {
"@v0": "https://v0.dev/chat/b/{name}",
"@acme": "https://registry.acme.com/resources/{name}.json",
"@lib": "https://lib.company.com/utilities/{name}",
"@ai": "https://ai-resources.com/r/{name}.json"
}
}注意:URL 中的
{name}占位符会在你运行npx shadcn@latest add @namespace/resource-name时自动解析并替换为资源名称。例如,@acme/button会变成https://registry.acme.com/resources/button.json。详情请参阅 URL 模式系统。
高级配置
对于需要认证或其他参数的注册表,请使用对象格式:
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}",
"X-API-Key": "${API_KEY}"
},
"params": {
"version": "latest",
"format": "json"
}
}
}
}注意:格式为
${VAR_NAME}的环境变量会自动从你的环境 (process.env) 中展开。这适用于 URL、标头和参数。例如,${REGISTRY_TOKEN}将被替换为process.env.REGISTRY_TOKEN的值。有关使用环境变量的详细信息,请参阅 认证与安全。
URL 模式系统
注册表 URL 支持以下占位符:
{name} 占位符(必填)
{name} 占位符会被替换为资源名称。
{
"@acme": "https://registry.acme.com/{name}.json"
}安装 @acme/button 时,URL 变为:https://registry.acme.com/button.json;安装 @acme/auth-utils 时,URL 变为:https://registry.acme.com/auth-utils.json。
{style} 占位符(可选)
{style} 占位符会被替换为当前的样式配置。
{
"@themes": "https://registry.example.com/{style}/{name}.json"
}当样式设置为 new-york 时,安装 @themes/card 解析为:https://registry.example.com/new-york/card.json
样式占位符是可选的。当你想要为同一资源提供不同版本时使用此功能。例如,你可以为每种样式提供不同版本的组件。
认证与安全
环境变量
使用环境变量安全地存储凭据:
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}然后设置环境变量:
REGISTRY_TOKEN=your_secret_token_here认证方法
Bearer Token (OAuth 2.0)
{
"@github": {
"url": "https://api.github.com/repos/org/registry/contents/{name}.json",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
}
}请求标头中的 API Key
{
"@private": {
"url": "https://api.company.com/registry/{name}",
"headers": {
"X-API-Key": "${API_KEY}"
}
}
}基本认证
{
"@internal": {
"url": "https://registry.company.com/{name}.json",
"headers": {
"Authorization": "Basic ${BASE64_CREDENTIALS}"
}
}
}查询参数认证
{
"@secure": {
"url": "https://registry.example.com/{name}.json",
"params": {
"api_key": "${API_KEY}",
"client_id": "${CLIENT_ID}",
"signature": "${REQUEST_SIGNATURE}"
}
}
}多种认证方法
某些注册表需要多种认证方法。
{
"@enterprise": {
"url": "https://api.enterprise.com/v2/registry/{name}",
"headers": {
"Authorization": "Bearer ${ACCESS_TOKEN}",
"X-API-Key": "${API_KEY}",
"X-Workspace-Id": "${WORKSPACE_ID}"
},
"params": {
"version": "latest"
}
}
}安全考虑
在使用带命名空间的注册表(尤其是第三方或公共注册表)时,安全性至关重要。以下是我们处理安全性的方式:
资源验证
在安装前,从注册表获取的所有资源都会根据我们的注册表项模式进行验证。这确保了:
- 结构验证:资源必须符合预期的 JSON 模式。
- 类型安全:验证资源类型(
registry:ui,registry:lib等)。 - 无任意代码执行:资源是数据文件,而非可执行脚本。
环境变量安全
用于认证的环境变量:
- 永不记录:CLI 永远不会记录或显示环境变量值。
- 运行时展开:变量仅在需要时展开,不会存储。
- 每个注册表隔离:每个注册表维护其自己的认证上下文。
安全配置示例:
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${PRIVATE_REGISTRY_TOKEN}"
}
}
}
}永远不要将实际令牌提交到版本控制中。请使用 .env.local。
PRIVATE_REGISTRY_TOKEN=actual_token_here强制使用 HTTPS
我们强烈建议对所有注册表 URL 使用 HTTPS。
- 加密传输:防止中间人攻击。
- 证书验证:确保你连接的是合法的注册表。
- 凭据保护:标头和令牌在传输过程中会被加密。
{
"registries": {
"@secure": "https://registry.example.com/{name}.json", // ✅ Good
"@insecure": "http://registry.example.com/{name}.json" // ❌ Avoid
}
}内容安全
来自注册表的资源被视为数据,而非代码。
- 仅 JSON 解析:资源必须是有效的 JSON。
- 模式验证:必须符合注册表项模式。
- 文件路径限制:文件只能写入已配置的路径。
- 无脚本执行:CLI 不会执行注册表资源中的任何代码。
注册表信任模型
命名空间系统基于信任模型运行:
- 信任你所安装的内容:只向你的配置中添加你信任的注册表。
- 显式配置:注册表必须在
components.json中显式配置。 - 无自动发现:CLI 永远不会自动添加注册表。
- 依赖透明:所有依赖项都在注册表项中清晰列出。
注册表运营商最佳实践
如果你正在运行自己的注册表:
- 始终使用 HTTPS:永远不要通过 HTTP 提供注册表内容。
- 实施认证:为私有注册表要求 API 密钥或令牌。
- 速率限制:保护你的注册表免受滥用。
- 内容验证:在提供资源之前对其进行验证。
安全注册表设置示例:
{
"@company": {
"url": "https://registry.company.com/v1/{name}.json",
"headers": {
"Authorization": "Bearer ${COMPANY_TOKEN}",
"X-Registry-Version": "1.0"
}
}
}安装前检查资源
CLI 提供安装内容的透明度。你可以使用以下命令查看注册表项的有效负载:
pnpm dlx shadcn@latest view @acme/button
这会将注册表项的有效负载输出到控制台。
依赖解析
基本依赖解析
资源可以拥有跨越不同注册表的依赖关系。
{
"name": "dashboard",
"type": "registry:block",
"registryDependencies": [
"@shadcn/card", // From default registry
"@v0/chart", // From v0 registry
"@acme/data-table", // From acme registry
"@lib/data-fetcher", // Utility library
"@ai/analytics-prompt" // AI prompt resource
]
}CLI 会自动解析并从各自的注册表中安装所有依赖项。
高级依赖解析
如果你正在开发注册表或需要自定义第三方资源,了解依赖关系在内部是如何解析的非常重要。
解析工作原理
当你运行 npx shadcn@latest add @namespace/resource 时,CLI 会执行以下操作:
- 清除注册表上下文以重新开始。
- 从指定注册表获取主资源。
- 递归解析来自各自注册表的依赖项。
- 应用拓扑排序以确保正确的安装顺序。
- 基于目标路径去重文件(最后一次安装生效)。
- 深度合并配置 (tailwind, cssVars, css, envVars)。
这意味着如果你运行以下命令:
pnpm dlx shadcn@latest add @acme/auth @custom/login-form
来自 @custom/login-form 的 login-form.ts 将覆盖来自 @acme/auth 的 login-form.ts,因为它是最后被解析的。
覆盖第三方资源
你可以利用依赖解析过程覆盖任何第三方资源,方法是将它们添加到你的自定义资源下的 registryDependencies 中,并使用你自己的自定义值进行覆盖。
示例:自定义第三方按钮
假设你想要自定义供应商注册表中的按钮:
1. 原始供应商按钮 (@vendor/button)
{
"name": "button",
"type": "registry:ui",
"files": [
{
"path": "components/ui/button.tsx",
"type": "registry:ui",
"content": "// Vendor's button implementation\nexport function Button() { ... }"
}
],
"cssVars": {
"light": {
"--button-bg": "blue"
}
}
}2. 创建你的自定义覆盖 (@my-company/custom-button)
{
"name": "custom-button",
"type": "registry:ui",
"registryDependencies": [
"@vendor/button" // Import original first
],
"cssVars": {
"light": {
"--button-bg": "purple" // Override the color
}
}
}3. 安装你的自定义版本:
pnpm dlx shadcn@latest add @my-company/custom-button
这会安装来自 @vendor/button 的原始按钮,然后用你自己的自定义值覆盖 cssVars。
高级覆盖模式
扩展而不替换
保留原始项并添加扩展:
{
"name": "extended-table",
"registryDependencies": ["@vendor/table"],
"files": [
{
"path": "components/ui/table-extended.tsx",
"content": "import { Table } from '@vendor/table'\n// Add your extensions\nexport function ExtendedTable() { ... }"
}
]
}这将安装来自 @vendor/table 的原始表格,然后将你的扩展添加到 components/ui/table-extended.tsx。
部分覆盖(多文件资源)
仅覆盖复杂组件中的特定文件:
{
"name": "custom-auth",
"registryDependencies": [
"@vendor/auth" // Has multiple files
],
"files": [
{
"path": "lib/auth-server.ts",
"type": "registry:lib",
"content": "// Your custom auth server"
}
]
}解析顺序示例
当你安装依赖于多个资源的 @custom/dashboard 时:
{
"name": "dashboard",
"registryDependencies": [
"@shadcn/card", // 1. Resolved first
"@vendor/chart", // 2. Resolved second
"@custom/card" // 3. Resolved last (overrides @shadcn/card)
]
}解析顺序:
@shadcn/card- 安装到components/ui/card.tsx@vendor/chart- 安装到components/ui/chart.tsx@custom/card- 覆盖components/ui/card.tsx(如果目标相同)
关键解析特性
- 来源追踪:每个资源都知道它来自哪个注册表,从而避免命名冲突。
- 防止循环依赖:自动检测并防止循环依赖。
- 智能安装顺序:首先安装依赖项,然后安装使用它们的资源。
版本控制
你可以使用查询参数为注册表资源实现版本控制。这允许用户锁定特定版本或使用不同的发布渠道。
基本版本参数
{
"@versioned": {
"url": "https://registry.example.com/{name}",
"params": {
"version": "v2"
}
}
}这会将 @versioned/button 解析为:https://registry.example.com/button?version=v2
动态版本选择
使用环境变量控制项目中的版本:
{
"@stable": {
"url": "https://registry.company.com/{name}",
"params": {
"version": "${REGISTRY_VERSION}"
}
}
}这使你能够:
- 在生产环境中设置
REGISTRY_VERSION=v1.2.3 - 针对每个环境(开发、预发、生产)进行覆盖
语义化版本控制
实现支持范围的语义化版本控制。
{
"@npm-style": {
"url": "https://registry.example.com/{name}",
"params": {
"semver": "^2.0.0",
"prerelease": "${ALLOW_PRERELEASE}"
}
}
}版本解析最佳实践
- 使用环境变量进行跨环境的版本控制。
- 提供合理的默认值(使用
${VAR:-default}语法)。 - 明确记录版本方案供注册表用户参考。
- 支持版本锁定以实现可复现的构建。
- 实施版本发现端点(例如
/versions/{name})。 - 适当地缓存版本化资源并使用正确的缓存标头。
CLI 命令
shadcn CLI 提供了几个用于处理命名空间注册表的命令。
添加资源
从任何已配置的注册表安装资源。
# Install from a specific registry
npx shadcn@latest add @v0/dashboard
# Install multiple resources
npx shadcn@latest add @acme/button @lib/utils @ai/prompt
# Install from URL directly
npx shadcn@latest add https://registry.example.com/button.json
# Install from local file
npx shadcn@latest add ./local-registry/button.json查看资源
安装前检查注册表项。
# View a resource from a registry
npx shadcn@latest view @acme/button
# View multiple resources
npx shadcn@latest view @v0/dashboard @shadcn/card
# View from URL
npx shadcn@latest view https://registry.example.com/button.jsonview 命令显示:
- 资源元数据(名称、类型、描述)
- 依赖项和注册表依赖项
- 将要安装的文件内容
- CSS 变量和 Tailwind 配置
- 所需的环境变量
搜索注册表
搜索注册表中可用的资源。
# Search a specific registry
npx shadcn@latest search @v0
# Search with query
npx shadcn@latest search @acme --query "auth"
# Search multiple registries
npx shadcn@latest search @v0 @acme @lib
# Limit results
npx shadcn@latest search @v0 --limit 10 --offset 20
# List all items (alias for search)
npx shadcn@latest list @acme搜索结果包括:
- 资源名称和类型
- 描述
- 注册表来源
错误处理
注册表未配置
如果你引用了未配置的注册表。
pnpm dlx shadcn@latest add @non-existent/component
错误
Unknown registry "@non-existent". Make sure it is defined in components.json as follows:
{
"registries": {
"@non-existent": "[URL_TO_REGISTRY]"
}
}缺失环境变量
如果未设置所需的环境变量。
Registry "@private" requires the following environment variables:
• REGISTRY_TOKEN
Set the required environment variables to your .env or .env.local file.资源未找到
404 未找到
The item at https://registry.company.com/button.json was not found. It may not exist at the registry.这通常意味着:
- 资源名称拼写错误。
- 注册表中不存在该资源。
- 注册表 URL 模式不正确。
认证失败
401 未授权
You are not authorized to access the item at https://api.company.com/button.json
Check your authentication credentials and environment variables.403 禁止访问
Access forbidden for https://api.company.com/button.json
Verify your API key has the necessary permissions.创建你自己的注册表
要使你的注册表与命名空间系统兼容,你可以提供任何类型的资源 —— 组件、库、工具、AI 提示词、主题、配置或任何其他可共享的代码/内容。
-
实施注册表项模式:你的注册表必须返回符合 注册表项模式 的 JSON。
-
支持 URL 模式:在你的 URL 模板中包含
{name},以便插入资源名称。 -
定义资源类型:使用适当的
type字段来标识你的资源(例如registry:ui,registry:lib等)。 -
处理认证(如果需要):通过标头或查询参数接受认证。
-
记录你的命名空间:为用户提供明确的说明来配置你的注册表。
{
"registries": {
"@your-registry": "https://your-domain.com/r/{name}.json"
}
}技术细节
解析器模式
命名空间解析器使用以下正则表达式模式:
/^(@[a-zA-Z0-9](?:[a-zA-Z0-9-_]*[a-zA-Z0-9])?)\/(.+)$/这确保了有效的命名空间格式和正确的组件名称提取。
解析过程
- 解析:从
@namespace/component中提取命名空间和组件名称。 - 查找:找到
@namespace的注册表配置。 - 构建 URL:用实际值替换占位符。
- 设置标头:如果已配置,应用认证标头。
- 获取:从解析后的 URL 检索组件。
- 验证:确保响应匹配注册表项模式。
- 解析依赖项:递归获取任何注册表依赖项。
跨注册表依赖
当组件具有来自不同注册表的依赖项时,解析器:
- 为每个注册表维护单独的认证上下文。
- 从各自的源解析每个依赖项。
- 基于目标路径去重文件。
- 合并来自所有源的配置(tailwind, cssVars 等)。
最佳实践
- 对 API 密钥和令牌等敏感数据使用环境变量。
- 用唯一、描述性的名称命名你的注册表。
- 为用户明确记录认证要求。
- 实施带有有用消息的正确错误响应。
- 尽可能缓存注册表响应以提高性能。
- 如果你的组件有多个主题,请支持样式变体。
故障排除
资源未找到
- 验证注册表 URL 是否正确且可访问。
- 检查 URL 中是否包含了
{name}占位符。 - 确保注册表中确实存在该资源。
- 确认资源类型与注册表提供的类型匹配。
认证问题
- 确认环境变量设置正确。
- 验证 API 密钥/令牌是否有效且未过期。
- 检查标头是否以正确的格式发送。
依赖冲突
- 检查来自不同注册表的同名资源。
- 使用全限定名称 (
@namespace/resource) 以避免歧义。 - 检查注册表之间是否存在循环依赖。
- 混合注册表时确保资源类型兼容。
本页内容
目录概述去中心化命名空间系统多注册表设置示例按资源类型按团队或部门按稳定性入门指南安装资源快速配置注册表命名规范配置基本配置高级配置URL 模式系统{name} 占位符(必填){style} 占位符(可选)认证与安全环境变量认证方法Bearer Token (OAuth 2.0)请求标头中的 API Key基本认证查询参数认证多种认证方法安全考虑资源验证环境变量安全强制使用 HTTPS内容安全注册表信任模型注册表运营商最佳实践安装前检查资源依赖解析基本依赖解析高级依赖解析解析工作原理覆盖第三方资源示例:自定义第三方按钮高级覆盖模式扩展而不替换部分覆盖(多文件资源)解析顺序示例关键解析特性版本控制基本版本参数动态版本选择语义化版本控制版本解析最佳实践CLI 命令添加资源查看资源搜索注册表错误处理注册表未配置缺失环境变量资源未找到认证失败创建你自己的注册表技术细节解析器模式解析过程跨注册表依赖最佳实践故障排除资源未找到认证问题依赖冲突