Practical Guide to Vercel Agent Skills
Vercel Agent Skills 實戰指南
Vercel has distilled over a decade of React and Next.js optimization expertise into a format that AI coding agents can understand and apply. This guide walks you through the two most impactful skills: React Best Practices (57 performance rules) and Web Design Guidelines (100+ UI/UX rules), showing you how to install, use, and get the most out of them.
Vercel 將十多年的 React 和 Next.js 優化經驗濃縮成 AI 程式碼代理可以理解和應用的格式。本指南將帶你深入了解兩個最具影響力的 skills:React Best Practices(57 條效能規則)和 Web Design Guidelines(100+ 條 UI/UX 規則),展示如何安裝、使用並充分發揮它們的價值。
1. What Are Vercel Agent Skills?
1. 什麼是 Vercel Agent Skills?
1.1 Overview
Vercel Agent Skills are pre-packaged knowledge modules maintained by Vercel Labs that extend AI coding assistants with battle-tested best practices. Think of them as "npm for AI agents" — installable packages that teach your AI assistant how to write better code.
Key characteristics:
- Platform-agnostic: Works with Claude Code, Cursor, Windsurf, Gemini CLI, and other AI coding tools
- Always up-to-date: Skills fetch the latest guidelines from Vercel's repositories
- Automatically activated: Agents detect when to apply these rules based on your requests
- Open source: Available on GitHub under MIT license
Repository stats (as of 2026):
- 18.6k stars, 1.7k forks
- 69.3k weekly installs for React Best Practices
- 52.5k weekly installs for Web Design Guidelines
1.1 概述
Vercel Agent Skills 是由 Vercel Labs 維護的預打包知識模組,用於擴展 AI 程式碼助手,提供經過實戰驗證的最佳實踐。可以把它們想像成「AI 代理的 npm」——可安裝的套件,教導你的 AI 助手如何寫出更好的程式碼。
主要特點:
- 跨平台:適用於 Claude Code、Cursor、Windsurf、Gemini CLI 和其他 AI 程式碼工具
- 始終最新:Skills 從 Vercel 的儲存庫獲取最新指南
- 自動啟動:代理根據你的請求偵測何時應用這些規則
- 開源:在 GitHub 上以 MIT 授權提供
儲存庫統計(截至 2026 年):
- 18.6k 星標,1.7k 分支
- React Best Practices 每週安裝量 69.3k
- Web Design Guidelines 每週安裝量 52.5k
1.2 Available Skills in the Repository
| Skill | Rules | Focus Area |
|---|---|---|
| react-best-practices | 57 rules, 8 categories | React/Next.js performance optimization |
| web-design-guidelines | 100+ rules | Accessibility, UX, forms, animations |
| react-native-guidelines | 16 rules, 7 sections | Mobile-specific patterns |
| composition-patterns | Compound components | Avoiding boolean prop proliferation |
| vercel-deploy | One command | Framework auto-detection for 40+ frameworks |
This guide focuses on the two most widely-used skills: react-best-practices and web-design-guidelines.
1.2 儲存庫中的可用 Skills
| Skill | 規則數 | 聚焦領域 |
|---|---|---|
| react-best-practices | 57 條規則,8 個類別 | React/Next.js 效能優化 |
| web-design-guidelines | 100+ 條規則 | 無障礙、UX、表單、動畫 |
| react-native-guidelines | 16 條規則,7 個章節 | 行動端特定模式 |
| composition-patterns | 複合元件 | 避免布林 prop 氾濫 |
| vercel-deploy | 單一命令 | 40+ 框架的自動偵測 |
本指南聚焦於兩個最廣泛使用的 skills:react-best-practices 和 web-design-guidelines。
2. Installation Methods
2. 安裝方法
2.1 Using the Skills CLI
The recommended way to install Vercel Agent Skills:
# Install all skills from the repository
npx skills add vercel-labs/agent-skills
# Install a specific skill
npx skills add https://github.com/vercel-labs/agent-skills --skill vercel-react-best-practices
npx skills add https://github.com/vercel-labs/agent-skills --skill web-design-guidelinesAfter installation, the skills are automatically available to your AI coding agent. No further configuration required.
2.2 Manual Installation
If you prefer manual setup or need to customize:
# Clone the repository
git clone https://github.com/vercel-labs/agent-skills.git
# Copy specific skills to your project
cp -r agent-skills/skills/react-best-practices .claude/skills/
cp -r agent-skills/skills/web-design-guidelines .claude/skills/2.3 Project-Level Integration with AGENTS.md
For team-wide adoption, add an AGENTS.md file to your project root:
# AGENTS.md
This project follows Vercel's best practices. When working on this codebase:
1. Apply react-best-practices rules when writing React/Next.js code
2. Apply web-design-guidelines when creating UI components
3. Prioritize CRITICAL and HIGH impact rules
Reference: https://github.com/vercel-labs/agent-skillsThis ensures all team members' AI assistants apply consistent standards.
2.1 使用 Skills CLI
安裝 Vercel Agent Skills 的建議方式:
# 從儲存庫安裝所有 skills
npx skills add vercel-labs/agent-skills
# 安裝特定 skill
npx skills add https://github.com/vercel-labs/agent-skills --skill vercel-react-best-practices
npx skills add https://github.com/vercel-labs/agent-skills --skill web-design-guidelines安裝後,skills 會自動提供給你的 AI 程式碼代理。不需要進一步配置。
2.2 手動安裝
如果你偏好手動設定或需要自訂:
# 複製儲存庫
git clone https://github.com/vercel-labs/agent-skills.git
# 將特定 skills 複製到你的專案
cp -r agent-skills/skills/react-best-practices .claude/skills/
cp -r agent-skills/skills/web-design-guidelines .claude/skills/2.3 專案級別整合:AGENTS.md
對於團隊廣泛採用,在專案根目錄添加 AGENTS.md 檔案:
# AGENTS.md
本專案遵循 Vercel 的最佳實踐。在此程式碼庫工作時:
1. 撰寫 React/Next.js 程式碼時應用 react-best-practices 規則
2. 建立 UI 元件時應用 web-design-guidelines
3. 優先處理 CRITICAL 和 HIGH 影響的規則
參考:https://github.com/vercel-labs/agent-skills這確保所有團隊成員的 AI 助手應用一致的標準。
3. React Best Practices: Deep Dive
3. React Best Practices:深入解析
3.1 The Eight Categories (Prioritized by Impact)
The framework organizes 57 rules into eight categories, ordered by performance impact. The philosophy is simple: "If a request waterfall adds 600ms of waiting time, it doesn't matter how optimized your useMemo calls are."
| Priority | Category | Impact Level | Prefix |
|---|---|---|---|
| 1 | Eliminating Waterfalls | CRITICAL | async- |
| 2 | Bundle Size Optimization | CRITICAL | bundle- |
| 3 | Server-Side Performance | HIGH | server- |
| 4 | Client-Side Data Fetching | MEDIUM-HIGH | client- |
| 5 | Re-render Optimization | MEDIUM | rerender- |
| 6 | Rendering Performance | MEDIUM | rendering- |
| 7 | JavaScript Performance | LOW-MEDIUM | js- |
| 8 | Advanced Patterns | LOW | advanced- |
3.2 When to Apply These Guidelines
The skill automatically activates when you:
- Create new React components or Next.js pages
- Implement data fetching (client or server-side)
- Audit code for performance concerns
- Refactor existing React/Next.js codebases
- Work on reducing bundle size or improving load times
3.1 八個類別(按影響排序)
該框架將 57 條規則組織成八個類別,按效能影響排序。理念很簡單:「如果一個請求瀑布增加了 600ms 的等待時間,你的 useMemo 調用優化得再好也沒用。」
| 優先級 | 類別 | 影響等級 | 前綴 |
|---|---|---|---|
| 1 | 消除瀑布流 | CRITICAL | async- |
| 2 | Bundle 大小優化 | CRITICAL | bundle- |
| 3 | 伺服器端效能 | HIGH | server- |
| 4 | 客戶端資料獲取 | MEDIUM-HIGH | client- |
| 5 | 重新渲染優化 | MEDIUM | rerender- |
| 6 | 渲染效能 | MEDIUM | rendering- |
| 7 | JavaScript 效能 | LOW-MEDIUM | js- |
| 8 | 進階模式 | LOW | advanced- |
3.2 何時應用這些指南
當你執行以下操作時,skill 會自動啟動:
- 建立新的 React 元件或 Next.js 頁面
- 實作資料獲取(客戶端或伺服器端)
- 審核程式碼的效能問題
- 重構現有的 React/Next.js 程式碼庫
- 致力於減少 bundle 大小或改善載入時間
3.3 Category 1: Eliminating Waterfalls (CRITICAL)
The most impactful category. Request waterfalls occur when async operations become sequential instead of parallel.
Rule: Defer awaits until necessary
// BAD: Blocks even when skipProcessing is true
async function processUser(userId: string, skipProcessing: boolean) {
const userData = await fetchUserData(userId)
if (skipProcessing) {
return { skipped: true }
}
return processData(userData)
}
// GOOD: Conditionally await only when needed
async function processUser(userId: string, skipProcessing: boolean) {
if (skipProcessing) {
return { skipped: true }
}
const userData = await fetchUserData(userId)
return processData(userData)
}Rule: Parallelize independent operations
// BAD: Sequential (total time = A + B + C)
const userProfile = await fetchUserProfile(userId)
const userPosts = await fetchUserPosts(userId)
const userSettings = await fetchUserSettings(userId)
// GOOD: Parallel (total time = max(A, B, C))
const [userProfile, userPosts, userSettings] = await Promise.all([
fetchUserProfile(userId),
fetchUserPosts(userId),
fetchUserSettings(userId),
])Rule: Start promises early in API routes
// BAD: Starts fetch after authentication completes
export async function GET(request: Request) {
await authenticateRequest(request)
const data = await fetchData()
return Response.json(data)
}
// GOOD: Start fetch while authenticating
export async function GET(request: Request) {
const dataPromise = fetchData() // Start immediately
await authenticateRequest(request)
const data = await dataPromise
return Response.json(data)
}3.3 類別 1:消除瀑布流(CRITICAL)
影響最大的類別。當非同步操作變成順序執行而非並行時,就會產生請求瀑布。
規則:延遲 await 直到必要時
// 不好:即使 skipProcessing 為 true 也會阻塞
async function processUser(userId: string, skipProcessing: boolean) {
const userData = await fetchUserData(userId)
if (skipProcessing) {
return { skipped: true }
}
return processData(userData)
}
// 好:只在需要時才條件性地 await
async function processUser(userId: string, skipProcessing: boolean) {
if (skipProcessing) {
return { skipped: true }
}
const userData = await fetchUserData(userId)
return processData(userData)
}規則:並行化獨立操作
// 不好:順序執行(總時間 = A + B + C)
const userProfile = await fetchUserProfile(userId)
const userPosts = await fetchUserPosts(userId)
const userSettings = await fetchUserSettings(userId)
// 好:並行執行(總時間 = max(A, B, C))
const [userProfile, userPosts, userSettings] = await Promise.all([
fetchUserProfile(userId),
fetchUserPosts(userId),
fetchUserSettings(userId),
])規則:在 API 路由中提早啟動 promises
// 不好:在認證完成後才開始 fetch
export async function GET(request: Request) {
await authenticateRequest(request)
const data = await fetchData()
return Response.json(data)
}
// 好:在認證的同時開始 fetch
export async function GET(request: Request) {
const dataPromise = fetchData() // 立即開始
await authenticateRequest(request)
const data = await dataPromise
return Response.json(data)
}3.4 Category 2: Bundle Size Optimization (CRITICAL)
Growing JavaScript bundles are a silent performance killer.
Rule: Import directly, avoid barrel files
// BAD: Imports entire icon library
import { ChevronIcon } from '@/components/icons'
// GOOD: Direct import path
import { ChevronIcon } from '@/components/icons/ChevronIcon'Rule: Dynamic imports for heavy components
// BAD: Loads chart library in initial bundle
import { Chart } from 'heavy-chart-library'
// GOOD: Load only when needed
const Chart = dynamic(() => import('heavy-chart-library').then(m => m.Chart), {
loading: () => <ChartSkeleton />,
})Rule: Defer third-party scripts until after hydration
// BAD: Blocks hydration
<Script src="https://analytics.example.com/script.js" />
// GOOD: Load after page is interactive
<Script
src="https://analytics.example.com/script.js"
strategy="afterInteractive"
/>Rule: Preload on interaction
// Preload the next page's code when user hovers
<Link
href="/dashboard"
onMouseEnter={() => router.prefetch('/dashboard')}
>
Dashboard
</Link>3.4 類別 2:Bundle 大小優化(CRITICAL)
不斷增長的 JavaScript bundle 是一個隱形的效能殺手。
規則:直接引入,避免 barrel 檔案
// 不好:引入整個圖示庫
import { ChevronIcon } from '@/components/icons'
// 好:直接引入路徑
import { ChevronIcon } from '@/components/icons/ChevronIcon'規則:對重型元件使用動態引入
// 不好:在初始 bundle 中載入圖表庫
import { Chart } from 'heavy-chart-library'
// 好:只在需要時載入
const Chart = dynamic(() => import('heavy-chart-library').then(m => m.Chart), {
loading: () => <ChartSkeleton />,
})規則:在 hydration 後才延遲載入第三方腳本
// 不好:阻塞 hydration
<Script src="https://analytics.example.com/script.js" />
// 好:在頁面可互動後載入
<Script
src="https://analytics.example.com/script.js"
strategy="afterInteractive"
/>規則:在互動時預載入
// 當使用者懸停時預載入下一頁的程式碼
<Link
href="/dashboard"
onMouseEnter={() => router.prefetch('/dashboard')}
>
Dashboard
</Link>3.5 Category 3: Server-Side Performance (HIGH)
Rule: Use React.cache() for request-level deduplication
// Without cache: Same data fetched multiple times per request
async function getUser(id: string) {
return db.user.findUnique({ where: { id } })
}
// With cache: Deduplicated within the same request
import { cache } from 'react'
const getUser = cache(async (id: string) => {
return db.user.findUnique({ where: { id } })
})Rule: Implement LRU caching across requests
With Vercel's Fluid Compute, LRU caching is especially effective because multiple concurrent requests can share the same function instance and cache.
import { LRUCache } from 'lru-cache'
const cache = new LRUCache<string, UserData>({
max: 500,
ttl: 1000 * 60 * 5, // 5 minutes
})
async function getUser(id: string) {
const cached = cache.get(id)
if (cached) return cached
const user = await db.user.findUnique({ where: { id } })
cache.set(id, user)
return user
}Rule: Minimize serialized data at RSC boundary
The React Server/Client boundary serializes all object properties into strings. Only pass fields that the client actually uses.
// BAD: Serializes entire user object
async function UserProfile({ userId }) {
const user = await getUser(userId)
return <ClientProfile user={user} />
}
// GOOD: Only pass needed fields
async function UserProfile({ userId }) {
const user = await getUser(userId)
return <ClientProfile name={user.name} avatar={user.avatar} />
}3.5 類別 3:伺服器端效能(HIGH)
規則:使用 React.cache() 進行請求級別去重
// 沒有 cache:同一請求中多次獲取相同資料
async function getUser(id: string) {
return db.user.findUnique({ where: { id } })
}
// 有 cache:在同一請求內去重
import { cache } from 'react'
const getUser = cache(async (id: string) => {
return db.user.findUnique({ where: { id } })
})規則:實作跨請求的 LRU 快取
使用 Vercel 的 Fluid Compute 時,LRU 快取特別有效,因為多個並發請求可以共享同一個函數實例和快取。
import { LRUCache } from 'lru-cache'
const cache = new LRUCache<string, UserData>({
max: 500,
ttl: 1000 * 60 * 5, // 5 分鐘
})
async function getUser(id: string) {
const cached = cache.get(id)
if (cached) return cached
const user = await db.user.findUnique({ where: { id } })
cache.set(id, user)
return user
}規則:在 RSC 邊界最小化序列化資料
React Server/Client 邊界會將所有物件屬性序列化為字串。只傳遞客戶端實際使用的欄位。
// 不好:序列化整個 user 物件
async function UserProfile({ userId }) {
const user = await getUser(userId)
return <ClientProfile user={user} />
}
// 好:只傳遞需要的欄位
async function UserProfile({ userId }) {
const user = await getUser(userId)
return <ClientProfile name={user.name} avatar={user.avatar} />
}3.6 Category 4-8: Additional Rules Summary
Client-Side Data Fetching (MEDIUM-HIGH):
- Use SWR for automatic deduplication and caching
- Deduplicate event listeners
- Use passive listeners for scroll events
- Version localStorage schemas to handle migrations
Re-render Optimization (MEDIUM):
- Avoid subscribing to unused state slices
- Memoize expensive computations
- Use primitive dependencies in hooks
- Derive state during render rather than in effects
- Leverage transitions for non-urgent updates
Rendering Performance (MEDIUM):
- Animate wrapper divs, not SVG elements directly
- Use
content-visibility: autofor long lists - Hoist static JSX outside components
- Reduce SVG precision (2 decimal places is enough)
- Handle hydration mismatches gracefully
- Prefer ternary over
&&for conditional rendering
JavaScript Performance (LOW-MEDIUM):
- Batch DOM/CSS changes to avoid layout thrashing
- Use Maps for O(1) lookups instead of array searches
- Cache property access and function results
- Combine iterations when processing arrays
- Check array length before operations
- Exit early from functions when possible
- Use Set for membership testing
Advanced Patterns (LOW):
- Store event handlers in refs for stable references
- Initialize expensive values once per app load
- Use
useLatestpattern for stable callback references
3.6 類別 4-8:其他規則摘要
客戶端資料獲取(MEDIUM-HIGH):
- 使用 SWR 進行自動去重和快取
- 去重事件監聽器
- 對捲動事件使用 passive 監聽器
- 為 localStorage schema 版本化以處理遷移
重新渲染優化(MEDIUM):
- 避免訂閱未使用的狀態切片
- 記憶化昂貴的計算
- 在 hooks 中使用原始類型依賴
- 在渲染期間衍生狀態而非在 effects 中
- 對非緊急更新使用 transitions
渲染效能(MEDIUM):
- 動畫化包裝 div,而非直接動畫 SVG 元素
- 對長列表使用
content-visibility: auto - 將靜態 JSX 提升到元件外部
- 減少 SVG 精度(2 位小數就足夠)
- 優雅地處理 hydration 不匹配
- 條件渲染時偏好三元運算子而非
&&
JavaScript 效能(LOW-MEDIUM):
- 批次 DOM/CSS 變更以避免 layout thrashing
- 使用 Maps 進行 O(1) 查找而非陣列搜索
- 快取屬性存取和函數結果
- 處理陣列時合併迭代
- 操作前先檢查陣列長度
- 盡可能提早從函數返回
- 使用 Set 進行成員測試
進階模式(LOW):
- 將事件處理器儲存在 refs 中以獲得穩定引用
- 每次應用載入時只初始化昂貴的值一次
- 使用
useLatest模式獲得穩定的回調引用
4. Web Design Guidelines: Deep Dive
4. Web Design Guidelines:深入解析
4.1 Overview
The Web Design Guidelines skill contains 100+ rules covering accessibility, performance, and UX. When invoked (via /web-design-guidelines or automatically when reviewing UI code), it:
- Fetches the latest guidelines from Vercel's repository
- Reads specified files or prompts for file selection
- Validates content against all applicable rules
- Reports findings in a concise
file:lineformat
4.2 Categories Covered
| Category | Focus Areas |
|---|---|
| Interactions | Keyboard navigation, focus management, hit targets |
| Animations | Motion preferences, GPU acceleration, interruptibility |
| Layout | Optical alignment, responsive design, safe areas |
| Content | Semantic HTML, typography, localization |
| Forms | Validation, labels, autocomplete, error handling |
| Performance | Throttling, virtualization, layout stability |
| Design | Shadows, contrast, color schemes, borders |
| Copywriting | Active voice, formatting, error messages |
4.1 概述
Web Design Guidelines skill 包含 100+ 條規則,涵蓋無障礙、效能和 UX。當被調用時(通過 /web-design-guidelines 或在審查 UI 程式碼時自動啟動),它會:
- 從 Vercel 的儲存庫獲取最新指南
- 讀取指定檔案或提示選擇檔案
- 根據所有適用規則驗證內容
- 以簡潔的
file:line格式報告發現
4.2 涵蓋的類別
| 類別 | 聚焦領域 |
|---|---|
| 互動 | 鍵盤導航、焦點管理、觸擊目標 |
| 動畫 | 動態偏好、GPU 加速、可中斷性 |
| 佈局 | 視覺對齊、響應式設計、安全區域 |
| 內容 | 語義化 HTML、排版、本地化 |
| 表單 | 驗證、標籤、自動完成、錯誤處理 |
| 效能 | 節流、虛擬化、佈局穩定性 |
| 設計 | 陰影、對比度、配色方案、邊框 |
| 文案 | 主動語態、格式、錯誤訊息 |
4.3 Interactions Rules
Keyboard Accessibility:
- All flows must be keyboard-operable following WAI-ARIA patterns
- Visible focus rings using
:focus-visibleover:focus - Focus traps in modals; move focus per WAI-ARIA patterns
Hit Targets:
/* Minimum hit targets */
.button {
min-height: 24px; /* Desktop minimum */
min-width: 24px;
}
@media (pointer: coarse) {
.button {
min-height: 44px; /* Mobile minimum */
min-width: 44px;
}
}Mobile Input Sizing:
/* Prevent iOS Safari auto-zoom */
input, select, textarea {
font-size: 16px; /* Minimum to prevent zoom */
}Preserve User Input:
- Never disable paste in inputs or textareas
- Hydration must preserve focus and input values
- Never disable browser zoom
4.3 互動規則
鍵盤無障礙:
- 所有流程必須遵循 WAI-ARIA 模式,可透過鍵盤操作
- 使用
:focus-visible而非:focus顯示可見的焦點環 - 在 modal 中使用焦點陷阱;按 WAI-ARIA 模式移動焦點
觸擊目標:
/* 最小觸擊目標 */
.button {
min-height: 24px; /* 桌面最小值 */
min-width: 24px;
}
@media (pointer: coarse) {
.button {
min-height: 44px; /* 行動端最小值 */
min-width: 44px;
}
}行動端輸入大小:
/* 防止 iOS Safari 自動縮放 */
input, select, textarea {
font-size: 16px; /* 防止縮放的最小值 */
}保留使用者輸入:
- 絕不禁用輸入框或文字區域的貼上功能
- Hydration 必須保留焦點和輸入值
- 絕不禁用瀏覽器縮放
4.4 Animations Rules
Respect Motion Preferences:
/* Provide reduced-motion variants */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}GPU-Accelerated Properties:
/* GOOD: Uses compositor */
.animated {
transform: translateX(100px);
opacity: 0.5;
}
/* BAD: Triggers layout */
.animated {
left: 100px;
width: 200px;
}Never Use transition: all:
/* BAD: Animates everything, including unintended properties */
.button {
transition: all 0.3s ease;
}
/* GOOD: Explicit properties */
.button {
transition: background-color 0.3s ease, transform 0.3s ease;
}Cross-Browser SVG Transforms:
<!-- Use <g> wrappers with transform-box for consistent behavior -->
<svg>
<g style="transform-box: fill-box; transform-origin: center;">
<rect class="animated" />
</g>
</svg>4.4 動畫規則
尊重動態偏好:
/* 提供減少動態的變體 */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}GPU 加速的屬性:
/* 好:使用合成器 */
.animated {
transform: translateX(100px);
opacity: 0.5;
}
/* 不好:觸發 layout */
.animated {
left: 100px;
width: 200px;
}絕不使用 transition: all:
/* 不好:動畫化所有東西,包括意外的屬性 */
.button {
transition: all 0.3s ease;
}
/* 好:明確的屬性 */
.button {
transition: background-color 0.3s ease, transform 0.3s ease;
}跨瀏覽器 SVG 變換:
<!-- 使用 <g> 包裝器配合 transform-box 以獲得一致行為 -->
<svg>
<g style="transform-box: fill-box; transform-origin: center;">
<rect class="animated" />
</g>
</svg>4.5 Forms Rules
Enter Key Behavior:
// Single input: Enter submits
<form onSubmit={handleSubmit}>
<input type="text" />
<button type="submit">Submit</button>
</form>
// Textarea: Cmd/Ctrl+Enter submits, Enter creates new line
<textarea
onKeyDown={(e) => {
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
handleSubmit()
}
}}
/>Every Control Needs a Label:
<!-- GOOD: Explicit label -->
<label for="email">Email</label>
<input id="email" type="email" />
<!-- GOOD: Wrapped label -->
<label>
Email
<input type="email" />
</label>
<!-- GOOD: aria-label for icon buttons -->
<button aria-label="Close dialog">
<CloseIcon />
</button>Submit Button States:
// Keep submit enabled until submission starts
// Then disable during in-flight request with spinner
<button
type="submit"
disabled={isSubmitting}
>
{isSubmitting ? <Spinner /> : 'Submit'}
</button>Input Types and Modes:
<!-- Use correct type and inputmode -->
<input type="email" inputmode="email" autocomplete="email" />
<input type="tel" inputmode="tel" autocomplete="tel" />
<input type="text" inputmode="numeric" pattern="[0-9]*" />4.5 表單規則
Enter 鍵行為:
// 單一輸入:Enter 提交
<form onSubmit={handleSubmit}>
<input type="text" />
<button type="submit">提交</button>
</form>
// Textarea:Cmd/Ctrl+Enter 提交,Enter 建立新行
<textarea
onKeyDown={(e) => {
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
handleSubmit()
}
}}
/>每個控制項都需要標籤:
<!-- 好:明確的標籤 -->
<label for="email">Email</label>
<input id="email" type="email" />
<!-- 好:包裝的標籤 -->
<label>
Email
<input type="email" />
</label>
<!-- 好:圖示按鈕的 aria-label -->
<button aria-label="關閉對話框">
<CloseIcon />
</button>提交按鈕狀態:
// 在提交開始前保持提交按鈕啟用
// 然後在請求進行中禁用並顯示 spinner
<button
type="submit"
disabled={isSubmitting}
>
{isSubmitting ? <Spinner /> : '提交'}
</button>輸入類型和模式:
<!-- 使用正確的 type 和 inputmode -->
<input type="email" inputmode="email" autocomplete="email" />
<input type="tel" inputmode="tel" autocomplete="tel" />
<input type="text" inputmode="numeric" pattern="[0-9]*" />4.6 Design Rules
Layered Shadows:
/* Mimic ambient + direct light with multiple layers */
.card {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.05), /* Ambient */
0 4px 8px rgba(0, 0, 0, 0.1); /* Direct */
}Nested Border Radii:
/* Child radius should be concentric with parent */
.parent {
border-radius: 16px;
padding: 8px;
}
.child {
border-radius: 8px; /* 16px - 8px padding = 8px */
}Contrast Guidelines:
/* Prefer APCA over WCAG 2 for perceptual accuracy */
/* Interactions increase contrast */
.button {
background: #666; /* Rest state */
}
.button:hover {
background: #555; /* Higher contrast on hover */
}
.button:active {
background: #444; /* Even higher on active */
}Theme Color:
<!-- Match browser UI to page background -->
<meta name="theme-color" content="#000000" />
<style>
/* Set color-scheme for dark themes */
html {
color-scheme: dark;
}
</style>4.6 設計規則
分層陰影:
/* 用多層模擬環境光 + 直射光 */
.card {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.05), /* 環境光 */
0 4px 8px rgba(0, 0, 0, 0.1); /* 直射光 */
}嵌套邊框半徑:
/* 子元素半徑應與父元素同心 */
.parent {
border-radius: 16px;
padding: 8px;
}
.child {
border-radius: 8px; /* 16px - 8px padding = 8px */
}對比度指南:
/* 偏好 APCA 而非 WCAG 2 以獲得感知準確性 */
/* 互動增加對比度 */
.button {
background: #666; /* 靜止狀態 */
}
.button:hover {
background: #555; /* 懸停時更高對比度 */
}
.button:active {
background: #444; /* 點擊時更高 */
}主題色:
<!-- 讓瀏覽器 UI 匹配頁面背景 -->
<meta name="theme-color" content="#000000" />
<style>
/* 為深色主題設定 color-scheme */
html {
color-scheme: dark;
}
</style>4.7 Content and Localization Rules
Semantic HTML First:
<!-- Prefer native elements over ARIA -->
<!-- BAD -->
<div role="button" tabindex="0" onclick="...">Click me</div>
<!-- GOOD -->
<button onclick="...">Click me</button>Locale-Aware Formatting:
// Format dates, times, numbers for user's locale
const formatter = new Intl.DateTimeFormat(navigator.language, {
dateStyle: 'medium',
timeStyle: 'short',
})
// Prefer language settings over location
// Use Accept-Language header, not IP/GPS
const language = request.headers.get('Accept-Language')Typography Details:
<!-- Use proper characters -->
<p>Loading…</p> <!-- Ellipsis character, not ... -->
<p>"Hello"</p> <!-- Curly quotes, not straight -->
<p>10 MB</p> <!-- Non-breaking space for units -->4.7 內容和本地化規則
語義化 HTML 優先:
<!-- 偏好原生元素而非 ARIA -->
<!-- 不好 -->
<div role="button" tabindex="0" onclick="...">點擊我</div>
<!-- 好 -->
<button onclick="...">點擊我</button>本地化格式:
// 為使用者的語言環境格式化日期、時間、數字
const formatter = new Intl.DateTimeFormat(navigator.language, {
dateStyle: 'medium',
timeStyle: 'short',
})
// 偏好語言設定而非位置
// 使用 Accept-Language header,而非 IP/GPS
const language = request.headers.get('Accept-Language')排版細節:
<!-- 使用正確的字元 -->
<p>載入中…</p> <!-- 省略號字元,而非 ... -->
<p>"你好"</p> <!-- 彎引號,而非直引號 -->
<p>10 MB</p> <!-- 單位使用不換行空格 -->5. Using Skills in Practice
5. 實際使用 Skills
5.1 Natural Language Invocation
After installation, skills activate automatically based on your requests. Simply describe what you want:
"Help me optimize this Next.js page for performance"
→ Activates react-best-practices
"Review my UI components for accessibility"
→ Activates web-design-guidelines
"Check if this form follows best practices"
→ Activates web-design-guidelines (forms section)
"Audit this code for bundle size issues"
→ Activates react-best-practices (bundle category)5.2 Explicit Invocation
For more targeted reviews:
# In Claude Code or Cursor
/react-best-practices src/components/Dashboard.tsx
/web-design-guidelines src/components/Form.tsx5.3 Combining Skills
For comprehensive reviews, both skills can be used together:
"Review this component for both performance and accessibility"
→ Agent applies rules from both skills
"Create a new form component following Vercel's guidelines"
→ Agent references both react-best-practices and web-design-guidelines5.4 Code Review Workflow
A typical AI-assisted code review with Vercel skills:
- Initial Request: "Review this PR for performance and UX issues"
- Agent Actions:
- Loads react-best-practices and web-design-guidelines
- Scans changed files
- Identifies violations by category and priority
- Output Format:
src/components/UserList.tsx:45 - [CRITICAL] async-waterfall: Sequential awaits should be parallelized src/components/Form.tsx:23 - [HIGH] forms-label: Input missing associated label src/components/Button.tsx:12 - [MEDIUM] design-contrast: Hover state needs higher contrast
5.1 自然語言調用
安裝後,skills 會根據你的請求自動啟動。只需描述你想要什麼:
「幫我優化這個 Next.js 頁面的效能」
→ 啟動 react-best-practices
「審查我的 UI 元件的無障礙性」
→ 啟動 web-design-guidelines
「檢查這個表單是否遵循最佳實踐」
→ 啟動 web-design-guidelines(表單部分)
「審核這段程式碼的 bundle 大小問題」
→ 啟動 react-best-practices(bundle 類別)5.2 明確調用
對於更有針對性的審查:
# 在 Claude Code 或 Cursor 中
/react-best-practices src/components/Dashboard.tsx
/web-design-guidelines src/components/Form.tsx5.3 組合 Skills
對於全面審查,可以同時使用兩個 skills:
「審查這個元件的效能和無障礙性」
→ 代理應用兩個 skills 的規則
「根據 Vercel 的指南建立一個新的表單元件」
→ 代理參考 react-best-practices 和 web-design-guidelines5.4 程式碼審查工作流程
使用 Vercel skills 的典型 AI 輔助程式碼審查:
- 初始請求:「審查這個 PR 的效能和 UX 問題」
- 代理動作:
- 載入 react-best-practices 和 web-design-guidelines
- 掃描變更的檔案
- 按類別和優先級識別違規
- 輸出格式:
src/components/UserList.tsx:45 - [CRITICAL] async-waterfall: 順序 await 應該並行化 src/components/Form.tsx:23 - [HIGH] forms-label: 輸入框缺少關聯的標籤 src/components/Button.tsx:12 - [MEDIUM] design-contrast: 懸停狀態需要更高對比度
6. Best Practices for Skill Usage
6. Skill 使用的最佳實踐
6.1 Prioritize by Impact
Don't try to fix everything at once. Follow the priority order:
- CRITICAL first: Eliminate waterfalls and bundle size issues
- HIGH next: Server-side performance and accessibility
- MEDIUM: Re-renders, animations, forms
- LOW: JavaScript micro-optimizations
6.2 Context-Appropriate Application
Not every rule applies to every situation:
| Context | Focus On |
|---|---|
| Landing pages | Bundle size, animations, performance |
| Dashboards | Re-renders, data fetching, virtualization |
| Forms | Labels, validation, autocomplete, error handling |
| Mobile apps | Hit targets, input sizing, touch interactions |
6.3 Gradual Adoption
For existing codebases:
- Start with new code: Apply skills to new components and features
- Audit critical paths: Review high-traffic pages first
- Incremental refactoring: Fix issues during related work, not all at once
- Team alignment: Share AGENTS.md so all team members' AI assistants follow the same standards
6.4 Keeping Skills Updated
Skills fetch the latest guidelines automatically, but you can also:
# Update skills manually
npx skills update vercel-labs/agent-skills
# Check for updates
npx skills list --check-updates6.1 按影響優先排序
不要試圖一次修復所有問題。遵循優先順序:
- 先處理 CRITICAL:消除瀑布流和 bundle 大小問題
- 接著 HIGH:伺服器端效能和無障礙性
- 然後 MEDIUM:重新渲染、動畫、表單
- 最後 LOW:JavaScript 微優化
6.2 根據情境適當應用
並非每條規則都適用於每種情況:
| 情境 | 聚焦於 |
|---|---|
| 著陸頁 | Bundle 大小、動畫、效能 |
| 儀表板 | 重新渲染、資料獲取、虛擬化 |
| 表單 | 標籤、驗證、自動完成、錯誤處理 |
| 行動應用 | 觸擊目標、輸入大小、觸控互動 |
6.3 漸進式採用
對於現有程式碼庫:
- 從新程式碼開始:對新元件和功能應用 skills
- 審核關鍵路徑:優先審查高流量頁面
- 增量重構:在相關工作期間修復問題,而非一次全部處理
- 團隊對齊:分享 AGENTS.md 讓所有團隊成員的 AI 助手遵循相同標準
6.4 保持 Skills 更新
Skills 會自動獲取最新指南,但你也可以:
# 手動更新 skills
npx skills update vercel-labs/agent-skills
# 檢查更新
npx skills list --check-updates7. Summary
7. 總結
Key Takeaways
React Best Practices:
- 57 rules across 8 categories, prioritized by impact
- Focus on CRITICAL issues first: waterfalls and bundle size
- Real production patterns from 10+ years of React/Next.js experience
- Automatically activates when writing or reviewing React code
Web Design Guidelines:
- 100+ rules covering accessibility, UX, forms, animations, and design
- Comprehensive coverage from keyboard navigation to typography
- Fetches latest guidelines from Vercel's repository
- Activates when reviewing UI code or creating components
Installation:
npx skills add vercel-labs/agent-skillsResources:
- GitHub: vercel-labs/agent-skills
- GitHub: vercel-labs/web-interface-guidelines
- Vercel Design Guidelines
- Vercel Blog: Introducing React Best Practices
- Skills.sh: React Best Practices
- Skills.sh: Web Design Guidelines
These skills represent a significant shift in how best practices are distributed — not as documentation you have to remember, but as knowledge that your AI assistant actively applies. Install once, and every code review, every new component, and every refactoring session benefits from Vercel's accumulated expertise.
關鍵要點
React Best Practices:
- 57 條規則,8 個類別,按影響排序
- 先聚焦於 CRITICAL 問題:瀑布流和 bundle 大小
- 來自 10+ 年 React/Next.js 經驗的真實生產模式
- 撰寫或審查 React 程式碼時自動啟動
Web Design Guidelines:
- 100+ 條規則,涵蓋無障礙、UX、表單、動畫和設計
- 從鍵盤導航到排版的全面覆蓋
- 從 Vercel 的儲存庫獲取最新指南
- 審查 UI 程式碼或建立元件時啟動
安裝:
npx skills add vercel-labs/agent-skills資源:
- GitHub: vercel-labs/agent-skills
- GitHub: vercel-labs/web-interface-guidelines
- Vercel Design Guidelines
- Vercel Blog: Introducing React Best Practices
- Skills.sh: React Best Practices
- Skills.sh: Web Design Guidelines
這些 skills 代表了最佳實踐分發方式的重大轉變——不再是你必須記住的文件,而是你的 AI 助手會主動應用的知識。安裝一次,每次程式碼審查、每個新元件、每次重構都能受益於 Vercel 累積的專業知識。