frontend-ui
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese<objective>
Enterprise-grade frontend skill for auditing and building world-class SaaS UIs. Covers Tailwind CSS v4 (CSS-first config), shadcn/ui (2026), Next.js 15+ App Router **or Vite SPA** with React 19.
Production SaaS: dashboards, pricing pages, data tables, onboarding, role-based UI — with WCAG 2.1 AA accessibility and Core Web Vitals performance baked in.
</objective>
<quick_start>
<objective>
面向企业级前端的技能指南,用于审计和构建世界级SaaS界面。涵盖Tailwind CSS v4(CSS优先配置)、shadcn/ui(2026版本)、搭配React 19的Next.js 15+ App Router **或Vite SPA**。
可用于构建生产级SaaS产品:仪表盘、定价页、数据表格、引导流程、基于角色的界面——内置WCAG 2.1 AA无障碍标准和Core Web Vitals性能优化。
</objective>
<quick_start>
Setup: Tailwind v4 + shadcn/ui
环境搭建:Tailwind v4 + shadcn/ui
bash
npx create-next-app@latest my-app --typescript --tailwind --eslint --app --src-dir
cd my-app && npx shadcn@latest init
npx shadcn@latest add button card dialog table formbash
npx create-next-app@latest my-app --typescript --tailwind --eslint --app --src-dir
cd my-app && npx shadcn@latest init
npx shadcn@latest add button card dialog table formTailwind v4 — CSS-First (No tailwind.config.js)
Tailwind v4 — CSS优先配置(无需tailwind.config.js)
css
/* app/globals.css */
@import "tailwindcss";
@theme inline {
--color-background: oklch(1 0 0);
--color-foreground: oklch(0.145 0 0);
--color-primary: oklch(0.205 0.042 264.695);
--color-primary-foreground: oklch(0.985 0 0);
--radius-lg: 0.5rem;
--radius-md: calc(var(--radius-lg) - 2px);
--radius-sm: calc(var(--radius-lg) - 4px);
}css
/* app/globals.css */
@import "tailwindcss";
@theme inline {
--color-background: oklch(1 0 0);
--color-foreground: oklch(0.145 0 0);
--color-primary: oklch(0.205 0.042 264.695);
--color-primary-foreground: oklch(0.985 0 0);
--radius-lg: 0.5rem;
--radius-md: calc(var(--radius-lg) - 2px);
--radius-sm: calc(var(--radius-lg) - 4px);
}Component Anatomy (shadcn/ui 2026)
组件结构(shadcn/ui 2026)
tsx
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
{
variants: {
variant: { default: "bg-primary text-primary-foreground", outline: "border border-input" },
size: { default: "h-10 px-4 py-2", sm: "h-9 px-3", lg: "h-11 px-8" },
},
defaultVariants: { variant: "default", size: "default" },
}
)
// React 19: ref is a regular prop — no forwardRef
// data-slot: styling hook for parent overrides
function Button({ className, variant, size, ref, ...props }:
React.ComponentProps<"button"> & VariantProps<typeof buttonVariants>) {
return <button ref={ref} data-slot="button"
className={cn(buttonVariants({ variant, size, className }))} {...props} />
}tsx
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
{
variants: {
variant: { default: "bg-primary text-primary-foreground", outline: "border border-input" },
size: { default: "h-10 px-4 py-2", sm: "h-9 px-3", lg: "h-11 px-8" },
},
defaultVariants: { variant: "default", size: "default" },
}
)
// React 19: ref为常规属性 — 无需forwardRef
// data-slot:用于父组件覆盖样式的钩子
function Button({ className, variant, size, ref, ...props }:
React.ComponentProps<"button"> & VariantProps<typeof buttonVariants>) {
return <button ref={ref} data-slot="button"
className={cn(buttonVariants({ variant, size, className }))} {...props} />
}cn() Utility
cn() 工具函数
ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) }ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) }Vite SPA Alternative
Vite SPA替代方案
bash
npm create vite@latest my-app -- --template react-ts
cd my-app && npm i -D @tailwindcss/vite && npx shadcn@latest initKey differences from Next.js:
- plugin (not postcss) — faster HMR, native Vite integration
@tailwindcss/vite - env prefix (not
VITE_), accessed viaNEXT_PUBLIC_import.meta.env - Client-only — no Server Components, use React Query for data fetching
- +
React.lazy()replaces<Suspense>for code splittingdynamic() - Routing via React Router v7 or TanStack Router (not file-based)
Tailwind v4, shadcn/ui, component patterns, accessibility, forms, and performance guidance all apply equally to Vite SPAs. Only routing and data fetching genuinely differ.
See and .
</quick_start>
reference/vite-react-setup.mdreference/spa-routing.md<success_criteria>
Enterprise SaaS frontend is production-ready when:
- Accessible: WCAG 2.1 AA — keyboard nav, screen reader, focus management, 4.5:1 contrast
- Performant: LCP < 2.5s, INP < 200ms, CLS < 0.1 on 4G mobile
- Responsive: Mobile-first, works 320px-2560px, container queries for components
- Secure: No XSS vectors, CSP headers, sanitized user content
- Themed: Dark mode via CSS, design tokens in @theme, consistent spacing/color
- Composable: Server Components default, client boundary pushed to leaves
- Typed: TypeScript strict, Zod validation on all forms, no </success_criteria>
any
<core_principles>
- Server-First — Default to Server Components. Add only for interactivity. Push client boundaries to leaf components.
"use client" - Accessible-by-Default — Semantic HTML first (,
<nav>,<main>). ARIA only when native semantics insufficient.<article> - Composition Over Configuration — Small composable components. Compound pattern for complex UI. Context at boundaries.
- Progressive Disclosure — Essential info first. Reveal complexity on demand. Reduce cognitive load.
- Mobile-First — Design for smallest screen, enhance upward. Container queries for components. Touch targets >= 44px.
- Design Tokens — All visual values in CSS . Never hardcode. OKLCH for perceptual uniformity.
@theme - Type Safety E2E — Zod schemas shared client/server. over manual interfaces. </core_principles>
React.ComponentProps<>
<tailwind_v4>
bash
npm create vite@latest my-app -- --template react-ts
cd my-app && npm i -D @tailwindcss/vite && npx shadcn@latest init与Next.js的主要差异:
- 使用插件(而非postcss)——更快的热模块替换(HMR),原生Vite集成
@tailwindcss/vite - 环境变量前缀为(而非
VITE_),通过NEXT_PUBLIC_访问import.meta.env - 仅客户端渲染——无服务端组件,使用React Query进行数据获取
- 用+
React.lazy()替代<Suspense>实现代码分割dynamic() - 路由使用React Router v7或TanStack Router(而非文件系统路由)
Tailwind v4、shadcn/ui、组件模式、无障碍设计、表单和性能优化指南同样适用于Vite SPA,仅路由和数据获取部分存在差异。
详情请查看和。
</quick_start>
reference/vite-react-setup.mdreference/spa-routing.md<success_criteria>
企业级SaaS前端达到生产就绪标准需满足:
- 无障碍性:符合WCAG 2.1 AA标准——支持键盘导航、屏幕阅读器、焦点管理、4.5:1对比度
- 性能:LCP < 2.5秒,INP < 200毫秒,4G移动网络下CLS < 0.1
- 响应式:移动端优先,适配320px-2560px屏幕,组件使用容器查询
- 安全性:无XSS漏洞、配置CSP头部、用户内容已清理
- 主题化:通过CSS实现深色模式,中定义设计令牌,间距/颜色保持一致
@theme - 可组合性:默认使用服务端组件,客户端边界尽可能推向叶子节点
- 类型安全:开启TypeScript严格模式,所有表单使用Zod验证,无类型 </success_criteria>
any
<core_principles>
- 服务端优先 — 默认使用服务端组件。仅在需要交互时添加。将客户端边界尽可能推向最小的叶子组件。
"use client" - 默认无障碍 — 优先使用语义化HTML(如、
<nav>、<main>)。仅当原生语义不足时使用ARIA。<article> - 组合优于配置 — 小型可组合组件。复杂UI使用复合模式。在边界处使用Context。
- 渐进式披露 — 优先展示关键信息。按需展示复杂内容。降低认知负荷。
- 移动端优先 — 先为最小屏幕设计,再向上优化。组件使用容器查询。触摸目标尺寸≥44px。
- 设计令牌 — 所有视觉值定义在CSS 中。绝不硬编码。使用OKLCH实现感知均匀性。
@theme - 端到端类型安全 — 客户端与服务端共享Zod模式。使用替代手动定义接口。 </core_principles>
React.ComponentProps<>
<tailwind_v4>
Tailwind CSS v4 — Key Changes from v3
Tailwind CSS v4 — 与v3的主要差异
- No — All config via CSS
tailwind.config.jsdirective@theme - — Replaces
@import "tailwindcss"@tailwind base/components/utilities - OKLCH colors — Perceptually uniform, replaces hex/HSL
- Container queries built-in — ,
@container,@md:prefixes@lg: - — CSS-native file scanning (replaces
@sourcearray)content - 70% smaller CSS — Automatic unused style elimination
- — shadcn/ui bridge: tokens without generated utilities
@theme inline
css
@theme {
--color-brand-500: oklch(0.55 0.15 250);
--font-sans: "Inter", system-ui, sans-serif;
--breakpoint-xs: 475px;
--animate-slide-in: slide-in 0.2s ease-out;
}tsx
// Container queries — component-level responsive
<div className="@container">
<div className="grid grid-cols-1 @md:grid-cols-2 @lg:grid-cols-3 gap-4">
{items.map(item => <Card key={item.id} {...item} />)}
</div>
</div>Migration: — See .
</tailwind_v4>
npx @tailwindcss/upgradereference/tailwind-v4-setup.md<shadcn_ui>
- 无需— 所有配置通过CSS
tailwind.config.js指令完成@theme - — 替代
@import "tailwindcss"@tailwind base/components/utilities - OKLCH颜色 — 感知均匀的颜色空间,替代十六进制/HSL
- 内置容器查询 — 、
@container、@md:前缀@lg: - — CSS原生文件扫描(替代
@source数组)content - CSS体积减少70% — 自动移除未使用的样式
- — shadcn/ui桥接:无需生成工具类的令牌
@theme inline
css
@theme {
--color-brand-500: oklch(0.55 0.15 250);
--font-sans: "Inter", system-ui, sans-serif;
--breakpoint-xs: 475px;
--animate-slide-in: slide-in 0.2s ease-out;
}tsx
// 容器查询 — 组件级响应式
<div className="@container">
<div className="grid grid-cols-1 @md:grid-cols-2 @lg:grid-cols-3 gap-4">
{items.map(item => <Card key={item.id} {...item} />)}
</div>
</div>迁移指南:执行 — 详情查看。
</tailwind_v4>
npx @tailwindcss/upgradereference/tailwind-v4-setup.md<shadcn_ui>
shadcn/ui 2026
shadcn/ui 2026
- — Bridges tokens with Tailwind v4
@theme inline - — Attribute-based styling hooks (replaces className overrides)
data-slot - No — React 19 ref as prop
forwardRef - — Replaces
tw-animate-cssfor v4 compattailwindcss-animate - Radix or Base UI — Choose primitive library
tsx
// data-slot: parent can target child styles
function Card({ className, ref, ...props }: React.ComponentProps<"div">) {
return <div ref={ref} data-slot="card" className={cn("rounded-xl border bg-card", className)} {...props} />
}
// Style from parent:
<div className="[&_[data-slot=card]]:shadow-lg">
<Card>...</Card>
</div>Dark mode: CSS custom property swap with class. See .
</shadcn_ui>
.darkreference/shadcn-setup.md<component_architecture>
- — 与Tailwind v4的令牌桥接
@theme inline - — 基于属性的样式钩子(替代className覆盖)
data-slot - 无需— React 19中ref为常规属性
forwardRef - — 替代
tw-animate-css以兼容v4tailwindcss-animate - Radix或Base UI — 可选择底层基础组件库
tsx
// data-slot:父组件可通过该属性定位子组件样式
function Card({ className, ref, ...props }: React.ComponentProps<"div">) {
return <div ref={ref} data-slot="card" className={cn("rounded-xl border bg-card", className)} {...props} />
}
// 父组件中修改样式:
<div className="[&_[data-slot=card]]:shadow-lg">
<Card>...</Card>
</div>深色模式:通过类切换CSS自定义属性。详情查看。
</shadcn_ui>
.darkreference/shadcn-setup.md<component_architecture>
Server vs Client Components
服务端组件 vs 客户端组件
| Server Component (default) | Client Component ( |
|---|---|
| Async data fetching, DB access | useState, useEffect, event handlers |
| Zero JS bundle, access to secrets | Browser APIs, third-party client libs |
Rule: Push to smallest leaf possible.
"use client"tsx
// Server page with client island
export default async function DashboardPage() {
const metrics = await getMetrics()
return (
<main>
<KPICards data={metrics} /> {/* Server-rendered */}
<RevenueChart data={metrics} /> {/* Client island */}
</main>
)
}| 服务端组件(默认) | 客户端组件( |
|---|---|
| 支持异步数据获取、数据库访问 | 支持useState、useEffect、事件处理 |
| 无JS包体积、可访问密钥 | 可使用浏览器API、第三方客户端库 |
规则:将尽可能添加到最小的叶子组件中。
"use client"tsx
// 包含客户端独立组件的服务端页面
export default async function DashboardPage() {
const metrics = await getMetrics()
return (
<main>
<KPICards data={metrics} /> {/* 服务端渲染 */}
<RevenueChart data={metrics} /> {/* 客户端独立组件 */}
</main>
)
}Key Patterns
核心模式
- Compound components — namespace composition
<Table>/<TableRow>/<TableCell> - cva variants — Type-safe style variants with
class-variance-authority - React.ComponentProps — Replace manual interfaces, ref as regular prop
- data-slot — External styling hooks for parent-child overrides
- Polymorphic (asChild) — pattern for rendering as different elements
Slot - SPA code splitting — +
React.lazy()replaces Next.js<Suspense>dynamic()
See for complete examples.
</component_architecture>
reference/component-patterns.md<saas_patterns>
- 复合组件 — 命名空间组合
<Table>/<TableRow>/<TableCell> - cva变体 — 使用实现类型安全的样式变体
class-variance-authority - React.ComponentProps — 替代手动定义接口,ref作为常规属性
- data-slot — 用于父子组件样式覆盖的外部钩子
- 多态组件(asChild) — 模式可将组件渲染为不同元素
Slot - SPA代码分割 — 用+
React.lazy()替代Next.js的<Suspense>dynamic()
完整示例请查看。
</component_architecture>
reference/component-patterns.md<saas_patterns>
Enterprise SaaS Patterns
企业级SaaS模式
Dashboard: Sidebar + Header + Main
仪表盘:侧边栏 + 头部 + 主内容区
tsx
<div className="flex h-screen">
<Sidebar className="w-64 hidden lg:flex" />
<div className="flex-1 flex flex-col">
<Header /> {/* Search, user menu, notifications */}
<main className="flex-1 overflow-auto p-6">
<KPIGrid metrics={metrics} />
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6">
<RevenueChart data={revenue} />
<ActivityFeed items={activities} />
</div>
</main>
</div>
</div>tsx
<div className="flex h-screen">
<Sidebar className="w-64 hidden lg:flex" />
<div className="flex-1 flex flex-col">
<Header /> {/* 搜索框、用户菜单、通知 */}
<main className="flex-1 overflow-auto p-6">
<KPIGrid metrics={metrics} />
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6">
<RevenueChart data={revenue} />
<ActivityFeed items={activities} />
</div>
</main>
</div>
</div>Pricing (3-Tier Conversion)
定价页(三档转化模式)
Anchor (low) | Conversion target (highlighted, "Most Popular") | Enterprise (custom)
Monthly/annual toggle, feature comparison table, social proof. See .
templates/pricing-page.tsx入门版(锚点) | 主推版(高亮,标注“最受欢迎”) | 企业版(定制)
支持月付/年付切换、功能对比表、社交证明。详情查看。
templates/pricing-page.tsxData Tables — shadcn Table + TanStack Table for sort/filter/paginate
数据表格 — shadcn Table + TanStack Table实现排序/筛选/分页
State Trio — Every data component needs: Loading (Skeleton) | Error (retry action) | Empty (guidance)
状态三重奏 — 所有数据组件需包含:加载状态(骨架屏)| 错误状态(重试操作)| 空状态(引导提示)
Role-Based UI — hasPermission(user, "scope")
guard for conditional rendering
hasPermission(user, "scope")基于角色的界面 — 使用hasPermission(user, "scope")
守卫实现条件渲染
hasPermission(user, "scope")See and .
</saas_patterns>
<accessibility>reference/saas-dashboard.mdreference/saas-pricing-checkout.md详情请查看和。
</saas_patterns>
<accessibility>reference/saas-dashboard.mdreference/saas-pricing-checkout.mdWCAG 2.1 AA
WCAG 2.1 AA标准
Semantic HTML first — , , , , ,
<header><nav><main><article><section><footer>| Pattern | Implementation |
|---|---|
| Keyboard nav | Tab/Shift+Tab, Arrow keys in menus/tabs, Escape to close |
| Focus management | Trap in dialogs, restore on close, skip link |
| ARIA live regions | |
| Form errors | |
| Loading states | |
| Contrast | 4.5:1 text, 3:1 UI components (OKLCH lightness channel) |
tsx
// Skip link
<a href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:z-50">
Skip to main content
</a>See for per-component ARIA patterns.
</accessibility>
reference/accessibility-checklist.md<state_management>
优先使用语义化HTML — 、、、、、
<header><nav><main><article><section><footer>| 模式 | 实现方式 |
|---|---|
| 键盘导航 | 支持Tab/Shift+Tab、菜单/标签页使用方向键、Esc关闭弹窗 |
| 焦点管理 | 弹窗中锁定焦点,关闭后恢复焦点,提供跳转链接 |
| ARIA实时区域 | 动态内容使用 |
| 表单错误 | 使用 |
| 加载状态 | 加载中按钮设置 |
| 对比度 | 文本对比度≥4.5:1,UI组件对比度≥3:1(通过OKLCH亮度通道实现) |
tsx
// 跳转链接
<a href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:z-50">
跳转到主内容
</a>各组件的ARIA模式详情请查看。
</accessibility>
reference/accessibility-checklist.md<state_management>
State Decision Tree
状态管理决策树
| State Type | Solution | Example |
|---|---|---|
| URL state | | Filters, pagination, tabs |
| Server data | React Query / SWR | API data, user profile |
| Local UI | | Form inputs, toggles |
| Shared parent-child | Lift state / Context | Accordion groups |
| Complex cross-cutting | Zustand | Cart, wizard, notifications |
Prefer URL state — shareable, bookmarkable, survives refresh.
</state_management>
<data_fetching>
| 状态类型 | 解决方案 | 示例 |
|---|---|---|
| URL状态 | | 筛选条件、分页、标签页 |
| 服务端数据 | React Query / SWR | API数据、用户资料 |
| 本地UI状态 | | 表单输入、开关 |
| 父子组件共享状态 | 状态提升 / Context | 手风琴组 |
| 复杂跨组件状态 | Zustand | 购物车、向导流程、通知 |
优先使用URL状态 — 可分享、可收藏、刷新后保留状态。
</state_management>
<data_fetching>
Data Fetching
数据获取
| Pattern | When | How |
|---|---|---|
| Server Components | Default | |
| Suspense streaming | Slow data | |
| Server Actions | Mutations | |
| React Query | Client real-time | |
| React Query (SPA) | Client-only apps | |
| </data_fetching> |
| 模式 | 适用场景 | 实现方式 |
|---|---|---|
| 服务端组件 | 默认方案 | |
| Suspense流式渲染 | 数据加载缓慢 | |
| 服务端操作 | 数据变更 | |
| React Query | 客户端实时数据 | |
| React Query(SPA) | 纯客户端应用 | 使用 |
| </data_fetching> |
Forms: RHF + Zod + shadcn Form + Server Actions
表单:RHF + Zod + shadcn Form + 服务端操作
- Shared Zod schema — Single source of truth for client validation and server action
- React Hook Form — with
useForm,zodResolvermode: "onBlur" - shadcn Form —
<Form>/<FormField>/<FormItem>/<FormLabel>/<FormMessage> - Server Action — on server, return field errors,
safeParserevalidatePath
tsx
const schema = z.object({
name: z.string().min(2),
email: z.string().email(),
})See and .
</forms>
<performance>reference/form-patterns.mdtemplates/form-with-server-action.tsx- 共享Zod模式 — 客户端验证和服务端操作的单一数据源
- React Hook Form — 使用搭配
useForm,设置zodResolvermode: "onBlur" - shadcn Form — 使用组件
<Form>/<FormField>/<FormItem>/<FormLabel>/<FormMessage> - 服务端操作 — 服务端使用,返回字段错误,调用
safeParserevalidatePath
tsx
const schema = z.object({
name: z.string().min(2),
email: z.string().email(),
})详情请查看和。
</forms>
<performance>reference/form-patterns.mdtemplates/form-with-server-action.tsxCore Web Vitals
Core Web Vitals核心指标
| Metric | Target | Quick Win |
|---|---|---|
| LCP < 2.5s | Main content visible | |
| INP < 200ms | Responsive interactions | Code-split heavy components with |
| CLS < 0.1 | No layout shift | Reserve space for images/fonts, Skeleton loaders |
Tailwind v4 produces 70% smaller CSS automatically. See .
</performance>
<references>
| Topic | Reference File | When to Load |
|-------|----------------|--------------|
| Tailwind v4 setup | `reference/tailwind-v4-setup.md` | New project, v3 migration |
| shadcn/ui setup | `reference/shadcn-setup.md` | Component library setup |
| Component patterns | `reference/component-patterns.md` | Building custom components |
| SaaS dashboard | `reference/saas-dashboard.md` | Dashboard layouts, KPI cards |
| Pricing + checkout | `reference/saas-pricing-checkout.md` | Pricing pages, Stripe UI |
| Accessibility | `reference/accessibility-checklist.md` | WCAG audit, ARIA patterns |
| Form patterns | `reference/form-patterns.md` | Multi-step forms, file upload |
| Performance | `reference/performance-optimization.md` | Core Web Vitals, Lighthouse |
| Vite + React setup | `reference/vite-react-setup.md` | New Vite SPA project |
| SPA routing | `reference/spa-routing.md` | React Router, TanStack Router |
</references>
<checklist>reference/performance-optimization.md| 指标 | 目标值 | 快速优化方案 |
|---|---|---|
| LCP < 2.5秒 | 主内容快速可见 | 使用 |
| INP < 200毫秒 | 交互响应迅速 | 对大型组件使用 |
| CLS < 0.1 | 无布局偏移 | 为图片/字体预留空间,使用骨架屏 |
Tailwind v4可自动将CSS体积减少70%。详情查看。
</performance>
<references>
| 主题 | 参考文件 | 适用场景 |
|-------|----------------|--------------|
| Tailwind v4配置 | `reference/tailwind-v4-setup.md` | 新项目、v3版本迁移 |
| shadcn/ui配置 | `reference/shadcn-setup.md` | 组件库配置 |
| 组件模式 | `reference/component-patterns.md` | 自定义组件开发 |
| SaaS仪表盘 | `reference/saas-dashboard.md` | 仪表盘布局、KPI卡片 |
| 定价页+结账流程 | `reference/saas-pricing-checkout.md` | 定价页、Stripe界面 |
| 无障碍设计 | `reference/accessibility-checklist.md` | WCAG审计、ARIA模式 |
| 表单模式 | `reference/form-patterns.md` | 多步骤表单、文件上传 |
| 性能优化 | `reference/performance-optimization.md` | Core Web Vitals、Lighthouse审计 |
| Vite+React配置 | `reference/vite-react-setup.md` | 新Vite SPA项目 |
| SPA路由 | `reference/spa-routing.md` | React Router、TanStack Router |
</references>
<checklist>reference/performance-optimization.mdEnterprise SaaS Pre-Ship Audit
企业级SaaS上线前审计清单
Accessibility
无障碍性
- Keyboard navigation for all interactive elements
- Screen reader announces content meaningfully
- Focus indicators visible, skip link present
- Color contrast >= 4.5:1 (text), >= 3:1 (UI)
- 所有交互元素支持键盘导航
- 屏幕阅读器可准确播报内容含义
- 焦点指示器可见,提供跳转链接
- 文本对比度≥4.5:1,UI组件对比度≥3:1
Performance
性能
- LCP < 2.5s, INP < 200ms, CLS < 0.1
- Images via next/image, fonts via next/font
- Heavy components code-split with dynamic()
- LCP < 2.5秒,INP < 200毫秒,CLS < 0.1
- 使用next/image加载图片,next/font加载字体
- 对大型组件使用dynamic()进行代码分割
Responsive
响应式
- Works 320px-2560px, touch targets >= 44px
- Container queries for reusable components
- 适配320px-2560px屏幕,触摸目标尺寸≥44px
- 可复用组件使用容器查询
Security
安全性
- No raw HTML injection without sanitization
- CSP headers, Zod validation client AND server
- 未清理的原始HTML不直接注入
- 配置CSP头部,客户端和服务端均使用Zod验证
UX
用户体验
- Loading / error / empty states for all data views
- Toast for mutations, confirm for destructive actions
- 所有数据视图包含加载/错误/空状态
- 数据变更时显示提示框,破坏性操作需确认