Skip to content

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

SkillRulesFocus Area
react-best-practices57 rules, 8 categoriesReact/Next.js performance optimization
web-design-guidelines100+ rulesAccessibility, UX, forms, animations
react-native-guidelines16 rules, 7 sectionsMobile-specific patterns
composition-patternsCompound componentsAvoiding boolean prop proliferation
vercel-deployOne commandFramework 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-practices57 條規則,8 個類別React/Next.js 效能優化
web-design-guidelines100+ 條規則無障礙、UX、表單、動畫
react-native-guidelines16 條規則,7 個章節行動端特定模式
composition-patterns複合元件避免布林 prop 氾濫
vercel-deploy單一命令40+ 框架的自動偵測

本指南聚焦於兩個最廣泛使用的 skills:react-best-practicesweb-design-guidelines


2. Installation Methods

2. 安裝方法

2.1 Using the Skills CLI

The recommended way to install Vercel Agent Skills:

bash
# 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-guidelines

After 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:

bash
# 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:

markdown
# 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-skills

This ensures all team members' AI assistants apply consistent standards.

2.1 使用 Skills CLI

安裝 Vercel Agent Skills 的建議方式:

bash
# 從儲存庫安裝所有 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 手動安裝

如果你偏好手動設定或需要自訂:

bash
# 複製儲存庫
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 檔案:

markdown
# 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."

PriorityCategoryImpact LevelPrefix
1Eliminating WaterfallsCRITICALasync-
2Bundle Size OptimizationCRITICALbundle-
3Server-Side PerformanceHIGHserver-
4Client-Side Data FetchingMEDIUM-HIGHclient-
5Re-render OptimizationMEDIUMrerender-
6Rendering PerformanceMEDIUMrendering-
7JavaScript PerformanceLOW-MEDIUMjs-
8Advanced PatternsLOWadvanced-

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消除瀑布流CRITICALasync-
2Bundle 大小優化CRITICALbundle-
3伺服器端效能HIGHserver-
4客戶端資料獲取MEDIUM-HIGHclient-
5重新渲染優化MEDIUMrerender-
6渲染效能MEDIUMrendering-
7JavaScript 效能LOW-MEDIUMjs-
8進階模式LOWadvanced-

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

typescript
// 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

typescript
// 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

typescript
// 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 直到必要時

typescript
// 不好:即使 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)
}

規則:並行化獨立操作

typescript
// 不好:順序執行(總時間 = 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

typescript
// 不好:在認證完成後才開始 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

typescript
// 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

typescript
// 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

typescript
// 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

typescript
// 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 檔案

typescript
// 不好:引入整個圖示庫
import { ChevronIcon } from '@/components/icons'

// 好:直接引入路徑
import { ChevronIcon } from '@/components/icons/ChevronIcon'

規則:對重型元件使用動態引入

typescript
// 不好:在初始 bundle 中載入圖表庫
import { Chart } from 'heavy-chart-library'

// 好:只在需要時載入
const Chart = dynamic(() => import('heavy-chart-library').then(m => m.Chart), {
  loading: () => <ChartSkeleton />,
})

規則:在 hydration 後才延遲載入第三方腳本

typescript
// 不好:阻塞 hydration
<Script src="https://analytics.example.com/script.js" />

// 好:在頁面可互動後載入
<Script
  src="https://analytics.example.com/script.js"
  strategy="afterInteractive"
/>

規則:在互動時預載入

typescript
// 當使用者懸停時預載入下一頁的程式碼
<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

typescript
// 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.

typescript
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.

typescript
// 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() 進行請求級別去重

typescript
// 沒有 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 快取特別有效,因為多個並發請求可以共享同一個函數實例和快取。

typescript
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 邊界會將所有物件屬性序列化為字串。只傳遞客戶端實際使用的欄位。

typescript
// 不好:序列化整個 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: auto for 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 useLatest pattern 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:

  1. Fetches the latest guidelines from Vercel's repository
  2. Reads specified files or prompts for file selection
  3. Validates content against all applicable rules
  4. Reports findings in a concise file:line format

4.2 Categories Covered

CategoryFocus Areas
InteractionsKeyboard navigation, focus management, hit targets
AnimationsMotion preferences, GPU acceleration, interruptibility
LayoutOptical alignment, responsive design, safe areas
ContentSemantic HTML, typography, localization
FormsValidation, labels, autocomplete, error handling
PerformanceThrottling, virtualization, layout stability
DesignShadows, contrast, color schemes, borders
CopywritingActive voice, formatting, error messages

4.1 概述

Web Design Guidelines skill 包含 100+ 條規則,涵蓋無障礙、效能和 UX。當被調用時(通過 /web-design-guidelines 或在審查 UI 程式碼時自動啟動),它會:

  1. 從 Vercel 的儲存庫獲取最新指南
  2. 讀取指定檔案或提示選擇檔案
  3. 根據所有適用規則驗證內容
  4. 以簡潔的 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-visible over :focus
  • Focus traps in modals; move focus per WAI-ARIA patterns

Hit Targets:

css
/* 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:

css
/* 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 模式移動焦點

觸擊目標:

css
/* 最小觸擊目標 */
.button {
  min-height: 24px;  /* 桌面最小值 */
  min-width: 24px;
}

@media (pointer: coarse) {
  .button {
    min-height: 44px;  /* 行動端最小值 */
    min-width: 44px;
  }
}

行動端輸入大小:

css
/* 防止 iOS Safari 自動縮放 */
input, select, textarea {
  font-size: 16px;  /* 防止縮放的最小值 */
}

保留使用者輸入:

  • 絕不禁用輸入框或文字區域的貼上功能
  • Hydration 必須保留焦點和輸入值
  • 絕不禁用瀏覽器縮放

4.4 Animations Rules

Respect Motion Preferences:

css
/* Provide reduced-motion variants */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

GPU-Accelerated Properties:

css
/* GOOD: Uses compositor */
.animated {
  transform: translateX(100px);
  opacity: 0.5;
}

/* BAD: Triggers layout */
.animated {
  left: 100px;
  width: 200px;
}

Never Use transition: all:

css
/* 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:

html
<!-- 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 動畫規則

尊重動態偏好:

css
/* 提供減少動態的變體 */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

GPU 加速的屬性:

css
/* 好:使用合成器 */
.animated {
  transform: translateX(100px);
  opacity: 0.5;
}

/* 不好:觸發 layout */
.animated {
  left: 100px;
  width: 200px;
}

絕不使用 transition: all

css
/* 不好:動畫化所有東西,包括意外的屬性 */
.button {
  transition: all 0.3s ease;
}

/* 好:明確的屬性 */
.button {
  transition: background-color 0.3s ease, transform 0.3s ease;
}

跨瀏覽器 SVG 變換:

html
<!-- 使用 <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:

tsx
// 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:

html
<!-- 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:

tsx
// 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:

html
<!-- 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 鍵行為:

tsx
// 單一輸入: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()
    }
  }}
/>

每個控制項都需要標籤:

html
<!-- 好:明確的標籤 -->
<label for="email">Email</label>
<input id="email" type="email" />

<!-- 好:包裝的標籤 -->
<label>
  Email
  <input type="email" />
</label>

<!-- 好:圖示按鈕的 aria-label -->
<button aria-label="關閉對話框">
  <CloseIcon />
</button>

提交按鈕狀態:

tsx
// 在提交開始前保持提交按鈕啟用
// 然後在請求進行中禁用並顯示 spinner
<button
  type="submit"
  disabled={isSubmitting}
>
  {isSubmitting ? <Spinner /> : '提交'}
</button>

輸入類型和模式:

html
<!-- 使用正確的 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:

css
/* 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:

css
/* Child radius should be concentric with parent */
.parent {
  border-radius: 16px;
  padding: 8px;
}
.child {
  border-radius: 8px;  /* 16px - 8px padding = 8px */
}

Contrast Guidelines:

css
/* 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:

html
<!-- 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 設計規則

分層陰影:

css
/* 用多層模擬環境光 + 直射光 */
.card {
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.05),   /* 環境光 */
    0 4px 8px rgba(0, 0, 0, 0.1);     /* 直射光 */
}

嵌套邊框半徑:

css
/* 子元素半徑應與父元素同心 */
.parent {
  border-radius: 16px;
  padding: 8px;
}
.child {
  border-radius: 8px;  /* 16px - 8px padding = 8px */
}

對比度指南:

css
/* 偏好 APCA 而非 WCAG 2 以獲得感知準確性 */
/* 互動增加對比度 */
.button {
  background: #666;  /* 靜止狀態 */
}
.button:hover {
  background: #555;  /* 懸停時更高對比度 */
}
.button:active {
  background: #444;  /* 點擊時更高 */
}

主題色:

html
<!-- 讓瀏覽器 UI 匹配頁面背景 -->
<meta name="theme-color" content="#000000" />

<style>
  /* 為深色主題設定 color-scheme */
  html {
    color-scheme: dark;
  }
</style>

4.7 Content and Localization Rules

Semantic HTML First:

html
<!-- Prefer native elements over ARIA -->
<!-- BAD -->
<div role="button" tabindex="0" onclick="...">Click me</div>

<!-- GOOD -->
<button onclick="...">Click me</button>

Locale-Aware Formatting:

typescript
// 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:

html
<!-- Use proper characters -->
<p>Loading…</p>        <!-- Ellipsis character, not ... -->
<p>"Hello"</p>          <!-- Curly quotes, not straight -->
<p>10&nbsp;MB</p>       <!-- Non-breaking space for units -->

4.7 內容和本地化規則

語義化 HTML 優先:

html
<!-- 偏好原生元素而非 ARIA -->
<!-- 不好 -->
<div role="button" tabindex="0" onclick="...">點擊我</div>

<!-- 好 -->
<button onclick="...">點擊我</button>

本地化格式:

typescript
// 為使用者的語言環境格式化日期、時間、數字
const formatter = new Intl.DateTimeFormat(navigator.language, {
  dateStyle: 'medium',
  timeStyle: 'short',
})

// 偏好語言設定而非位置
// 使用 Accept-Language header,而非 IP/GPS
const language = request.headers.get('Accept-Language')

排版細節:

html
<!-- 使用正確的字元 -->
<p>載入中…</p>          <!-- 省略號字元,而非 ... -->
<p>"你好"</p>           <!-- 彎引號,而非直引號 -->
<p>10&nbsp;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:

bash
# In Claude Code or Cursor
/react-best-practices src/components/Dashboard.tsx

/web-design-guidelines src/components/Form.tsx

5.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-guidelines

5.4 Code Review Workflow

A typical AI-assisted code review with Vercel skills:

  1. Initial Request: "Review this PR for performance and UX issues"
  2. Agent Actions:
    • Loads react-best-practices and web-design-guidelines
    • Scans changed files
    • Identifies violations by category and priority
  3. 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 明確調用

對於更有針對性的審查:

bash
# 在 Claude Code 或 Cursor 中
/react-best-practices src/components/Dashboard.tsx

/web-design-guidelines src/components/Form.tsx

5.3 組合 Skills

對於全面審查,可以同時使用兩個 skills:

「審查這個元件的效能和無障礙性」
→ 代理應用兩個 skills 的規則

「根據 Vercel 的指南建立一個新的表單元件」
→ 代理參考 react-best-practices 和 web-design-guidelines

5.4 程式碼審查工作流程

使用 Vercel skills 的典型 AI 輔助程式碼審查:

  1. 初始請求:「審查這個 PR 的效能和 UX 問題」
  2. 代理動作
    • 載入 react-best-practices 和 web-design-guidelines
    • 掃描變更的檔案
    • 按類別和優先級識別違規
  3. 輸出格式
    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:

  1. CRITICAL first: Eliminate waterfalls and bundle size issues
  2. HIGH next: Server-side performance and accessibility
  3. MEDIUM: Re-renders, animations, forms
  4. LOW: JavaScript micro-optimizations

6.2 Context-Appropriate Application

Not every rule applies to every situation:

ContextFocus On
Landing pagesBundle size, animations, performance
DashboardsRe-renders, data fetching, virtualization
FormsLabels, validation, autocomplete, error handling
Mobile appsHit targets, input sizing, touch interactions

6.3 Gradual Adoption

For existing codebases:

  1. Start with new code: Apply skills to new components and features
  2. Audit critical paths: Review high-traffic pages first
  3. Incremental refactoring: Fix issues during related work, not all at once
  4. 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:

bash
# Update skills manually
npx skills update vercel-labs/agent-skills

# Check for updates
npx skills list --check-updates

6.1 按影響優先排序

不要試圖一次修復所有問題。遵循優先順序:

  1. 先處理 CRITICAL:消除瀑布流和 bundle 大小問題
  2. 接著 HIGH:伺服器端效能和無障礙性
  3. 然後 MEDIUM:重新渲染、動畫、表單
  4. 最後 LOW:JavaScript 微優化

6.2 根據情境適當應用

並非每條規則都適用於每種情況:

情境聚焦於
著陸頁Bundle 大小、動畫、效能
儀表板重新渲染、資料獲取、虛擬化
表單標籤、驗證、自動完成、錯誤處理
行動應用觸擊目標、輸入大小、觸控互動

6.3 漸進式採用

對於現有程式碼庫:

  1. 從新程式碼開始:對新元件和功能應用 skills
  2. 審核關鍵路徑:優先審查高流量頁面
  3. 增量重構:在相關工作期間修復問題,而非一次全部處理
  4. 團隊對齊:分享 AGENTS.md 讓所有團隊成員的 AI 助手遵循相同標準

6.4 保持 Skills 更新

Skills 會自動獲取最新指南,但你也可以:

bash
# 手動更新 skills
npx skills update vercel-labs/agent-skills

# 檢查更新
npx skills list --check-updates

7. 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:

bash
npx skills add vercel-labs/agent-skills

Resources:

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 程式碼或建立元件時啟動

安裝:

bash
npx skills add vercel-labs/agent-skills

資源:

這些 skills 代表了最佳實踐分發方式的重大轉變——不再是你必須記住的文件,而是你的 AI 助手會主動應用的知識。安裝一次,每次程式碼審查、每個新元件、每次重構都能受益於 Vercel 累積的專業知識。