# 使用 Next.js 构建 SaaS 定价页面的提示

> 复制粘贴 AI 提示，使用 Next.js 与 Tailwind 构建 SaaS 定价页面，包含账单切换和 Stripe 就绪的计划数据。

**Type:** Prompt  
**Tools:** Cursor, Claude Code, Codex, Windsurf  
**Stack:** Next.js, TypeScript, Tailwind  
**Difficulty:** easy  
**Updated:** 2026-06-08

---

使用此提示生成一份精美且优化转化的定价页面，包含月度/年度账单切换、高亮的“最受欢迎”层级，以及直接连接 Stripe Checkout 的类型化计划配置——无占位数据。

## 主要提示

```txt title="Main Prompt"
You are working in a Next.js App Router project using TypeScript and Tailwind CSS v4.

Task: create a `/pricing` page with the following specification.

Plan data:
- Starter: $0/mo, $0/yr — 1 user, 5 projects, community support.
- Pro: $19/mo, $190/yr — 5 users, unlimited projects, email support. Mark as "Most Popular".
- Enterprise: $99/mo, $990/yr — unlimited users, SSO, dedicated support.

UI requirements:
- A client component `<PricingToggle>` with monthly/annual switch; annual shows "Save 17%".
- A `<PricingCard>` component per plan with: name, price, feature list, CTA button.
- "Most Popular" card has a highlighted border and badge.
- CTA buttons call `handleCheckout(planId, interval)` — stub it for now, we will wire Stripe later.
- The page file itself must be a Server Component; only the toggle and cards are Client Components.
- Use Tailwind utility classes only — no CSS modules, no inline styles.

Type requirements:
- Export a `Plan` interface from `src/lib/pricing.ts`.
- Plan data lives in that same file as a `const PLANS: Plan[]`.

Do NOT install any new packages. Stop and list all files before writing code.
```

## 实现说明

- 页面必须是服务器组件以便静态渲染；仅将 `'use client'` 提升到需要 `useState` 的切换和卡片组件上。
- `handleCheckout` 应接受 `(planId: string, interval: 'monthly' | 'annual')` —— 此签名与 Stripe Checkout 提示匹配，请保持稳定。
- Tailwind v4 使用 CSS 优先配置；除非已存在，否则避免使用 `tailwind.config.ts`。

## 预期文件更改

```txt
src/app/pricing/page.tsx            (new — Server Component)
src/components/PricingToggle.tsx    (new — Client Component)
src/components/PricingCard.tsx      (new — Client Component)
src/lib/pricing.ts                  (new — Plan type + PLANS constant)
```

## 验收标准

- `bun run build` 退出码为 0，无 TypeScript 错误。
- 切换月度/年度会更新所有三个卡片的价格，无需完整页面重新加载。
- “最受欢迎”徽标在 Pro 卡片上可见。
- 当点击 CTA 时，`handleCheckout` 被调用并传入正确的 `planId` 和 `interval`。

## 测试命令

```bash
bun run typecheck
bun run build
bun run dev
# open http://localhost:3000/pricing and verify toggle behavior
```

## 常见 AI 错误

- 将页面文件本身标记为 `'use client'`，这会破坏服务器渲染。
- 在 JSX 中硬编码价格，而非从 `PLANS` 派生。
- 使用不适用于 Tailwind v4 的 `tailwind.config.ts` `theme.extend` 模式。
- 忘记导出 `Plan` 类型，后续会破坏 Stripe Checkout 集成。

## 修复提示

```txt title="Fix Prompt"
The pricing page has type errors or the toggle doesn't work. Fix in this order:
1. Remove `'use client'` from `src/app/pricing/page.tsx` — only the child components need it.
2. Make sure `PricingToggle` uses `useState` for the billing interval and passes it down via props.
3. Confirm `handleCheckout` signature is `(planId: string, interval: 'monthly' | 'annual') => void`.
Show the corrected diff only — do not rewrite unrelated files.
```