在 Claude Code 中构建着陆页
一个用于在 Claude Code 中构建、发布和优化营销页面的完整工作设置。 完成大部分工作的五件事是:代码仓库、托管平台、品牌套件、性能优化和漏斗数据。 把握好这些,其余就是迭代。
在页面发布前有两种查看方式(第 4 节):一个供你和 Claude 使用的本地开发服务器,以及一个供非技术人员使用的 Claude Design。如果使用 Design,请先阅读第 4 节的硬性规定——那里没有撤销功能。
贯穿始终的主线:工作不是在部署时结束的。 一个在线但未被跟踪的页面是你无法优化的页面。
操作顺序
按顺序执行以下步骤。每一步都会让下一步更便宜。
- 先建仓库——在任何代码之前。版本控制是其他所有操作的撤销按钮。
- 其次配置托管和部署管道——在站点内容很少且部署失败代价为零时进行。
- 第三准备品牌套件——在写任何文案之前,确保第一稿就已经符合品牌规范。
- 构建页面——先做视觉/静态部分,再做交互,最后添加跟踪。
- 上线第一天就添加最少跟踪——然后根据真实数据优化速度和文案。
1. 使用代码仓库(GitHub 或同类工具)
如果你已经在使用 Claude Code,这一点很明显。如果你只是浅尝辄止,这是热身运动:代码仓库为你提供版本控制、云端备份,以及最重要的——一种部署策略。
main 分支是生产环境,除了通过你合并的 Pull Request 之外,任何内容都不能进入该分支。将此规则显式地写入 CLAUDE.md 文件——请参见 starters/CLAUDE.md。
工作循环
这是完整的循环。对于每一项工作,无论多小,都要执行这个循环。
- 确定版本号。 Claude 推荐一个,你同意它——或者你直接说出你想要的版本号。无论哪种方式,版本号在任何工作开始之前就要确定,并且决定权在你,而不是 Claude。
- Claude 创建分支——
git checkout -b v1.03。 - 你在分支中完成工作。 提交只进入该分支,不进入其他地方。
- Claude 将分支推送到 GitHub。
- Claude 提交 Pull Request。
- 你在 GitHub 上审查并批准,然后合并。 这就是部署。这是生产环境发生变化的唯一时刻,而且始终是一个人的决定。
git checkout main然后git pull。 不要跳过这一步。你的本地main现在落后了一次合并,从过时的main开始下一个分支会导致分歧、幽灵冲突以及无法快进的git pull。- 重复步骤 1,使用下一个版本号。
Claude 提议,你决定,Claude 执行。 版本号、合并和部署由你决定;分支、推送和提交 PR 由 Claude 完成。如果某个调用不明确,Claude 会询问。
有效的版本命名方式: v1.0x 用于补丁(文案、配置、小修复),v1.x 用于次要工作(新页面、新功能),v2.x 用于重新设计。
值得保留的两道审查关卡:
- 在合并之前审查整个分支的差异,而不仅仅是每个提交。 单个看起来没问题的提交组合起来可能产生真正的 bug。一次完整的“从分支点读取所有内容”的审查——最好由第二个审查者或一个新的代理进行——能够捕获按任务审查结构上无法发现的问题。
- 在任何收集用户数据的部署之前进行安全审查。 有一次对处理表单的分支进行审查,就发现了一个真正的漏洞:一个原始的对象展开 (raw object spread) 让访问者可以为服务器管理的字段提交值。请将其视为一道关卡,而不是一种装饰。
2. 托管在具有真正部署管道的地方
AWS Amplify 运行良好:其免费层可覆盖低流量着陆页,超出部分费用也很低。请查看当前条款——AWS 在 2025 年重组了其免费层。Netlify、Vercel 和 Cloudflare Pages 提供类似的模式。
真正的好处在于部署路径:合并一个 PR,站点便会重建并上线。
将代码仓库连接到托管平台是一个人们容易卡住的步骤,但它是一个点击路径,而不是配置文件:在托管平台的控制台中,创建一个新的 Web 应用 → 授权它访问你的 GitHub 账户 → 选择代码仓库和 main 分支 → 它会检测到你的构建规范 → 首次部署运行。从那时起,每次推送到该分支都会自动重建。在站点还是一个简单的“hello”页面时执行此操作,这样调试损坏的管道对你来说没有成本。
在第一天就设置好,趁它还很便宜:
- 从
main自动部署。 - 自定义域名并启用 HTTPS。
- 设置账单警报。 你刚刚将一张银行卡绑定到一个云账户。设定一个让你感到惊讶的数字作为预算警报——只需两分钟,它就能将一个低概率的讨厌意外转化为一封邮件。
- 安全标头——静态托管默认情况下不附带任何安全标头。
- 对基于内容哈希的构建资源设置长缓存
Cache-Control。这很容易,永久有效,否则因为永远不会阻塞任何东西而永远被推迟。
域名和 DNS,这里的陷阱是可预测的:
- 裸域名不能使用 CNAME 记录——
www.example.com可以,example.com不行。你需要 DNS 提供商的 ALIAS/ANAME 记录或托管平台自己的根域名选项。尽早决定你的规范 URL 是否包含www,并将另一个重定向到它。 - HTTPS 证书需要 DNS 记录来验证,并且在该记录解析之前不会颁发。给任何 DNS 更改几个小时的时间,然后再认为它有问题——传播延迟看起来和失败完全一样。
会浪费大量时间的部署陷阱:
- 确切知道哪些部分自动部署,哪些不自动部署。 如果你的栈的任何部分(无服务器函数、后端、worker)是通过单独的手动命令部署的,请用大写字母把它写在
CLAUDE.md中。经典的静默失败是合并了一个分支,其中可见的站点更新了,但后端没有,而且一切看起来都正常。 - 自动部署移除了你最后的检查点。 在“合并即部署”的模式下,PR 审查就是网关。验证必须在合并之前完成,而不是之后。
- 构建主机上的
npm ci比本地npm install更严格。 一个与package.json轻微不同步的锁文件在本地较新的 npm 上可以正常安装,但在主机较旧的 npm 上会导致构建失败。构建在主机上失败但在本地不失败?首先怀疑锁文件。 - 在构建规范中固定运行时版本,而不仅仅在版本文件中。 单独一个
.nvmrc不会被可靠地遵守——在构建命令中也调用版本管理器。 - 每个新的环境变量都需要在主机控制台中添加,与读取它的代码分开。这是一个出乎意料频繁出现的“为什么坏了”的答案。
- Content-Security-Policy 是会让你头疼的标头。 你的页面实际通信的每个第三方来源——分析工具、标签管理器、像素代码、字体、表单端点——都必须被加入白名单,放在正确的指令中,否则在生产环境中会被静默拦截,而在本地开发中却功能正常。症状:“跟踪在本地有效,上线后不触发任何东西。”在调试其他东西之前,先检查浏览器控制台中是否有 CSP 违规。
- 针对部署后的产物进行验证,而不是源文件。 通过检查真实的生成响应(
curl -I、浏览器开发者工具)来确认修复,而不是通过阅读本应生成它的配置。对于“我的更改是否真的部署了”也是如此——检查构建 ID/时间戳,而不仅仅是合并是否发生。
表单实际如何提交
静态托管没有后端。静态页面上的简单 <form> 不会做任何有用的事情——这会在第一天让人感到惊讶,而这正是页面的全部意义所在。三种现实的选择:
| 选项 | 适合的情况 | 注意点 |
|---|---|---|
| 托管表单服务 | 你想今天下午就让它工作 | 按量计算的月费;他们的品牌标识;你的数据由他们保管 |
| 无服务器函数(Lambda、Netlify/Cloudflare Functions) | 你想要控制权和接近零的成本 | 你现在要负责验证、垃圾邮件防护和 CORS |
| 你的 CRM 的嵌入式表单或 Webhook | 线索无论如何都需要进入 CRM | 嵌入的权重和样式限制;通常加载缓慢 |
无论选择哪个:
- CORS 会是你的第一个错误。 一个位于与你的页面不同来源的无服务器端点必须明确地将该来源加入白名单,否则浏览器会在请求发出之前就将其拦截。也要将 localhost 加入白名单,否则你无法在本地测试。
- 添加一个蜜罐字段(一个人类永远不会填写而机器人会填写的隐藏输入),并拒绝任何填写它的提交。这是最便宜的垃圾邮件过滤器。
- 永远不要直接将原始请求体展开写入你的数据库。 这就是访问者最终设置你本意为服务器控制字段的方式。明确地挑选出你想要的字段。
- 如果可能,保持端点处于热状态。 冷启动的无服务器函数会让页面上最重要的时刻——点击提交——感觉像是坏了。
3. 给 Claude 一个品牌套件——并强制它加载
这是整个列表中影响力最大的事情。至少,品牌套件包含:
你的产品 · 你的目标市场/客户画像 · 你的信息传递策略 · 你的颜色 · 你的字体 · 你的 Logo
把它放在一个文件夹里(brand/)。模板:starters/brand-kit/brand.md。
然后让它自动加载。 CLAUDE.md 中“读取品牌套件”的指令只是建议性的——它会被不一致地执行。一个能够 cat 文件到上下文中的 SessionStart 钩子是强制性的,不能被跳过。这一个简单的改动就是“有时符合品牌”和“默认符合品牌”之间的区别。请参见 starters/settings.json。
在会话开始时加载:品牌套件、一个简短的架构文档(站点是如何构建、托管和部署的),以及最近的会话日志。
结构化好品牌套件:
- 将“品牌的外观”与“品牌的语言”分开。 保持始终在线的文件精简——调色板、字体、Logo、产品、受众。将更深入的语气/信息传递材料作为“在做文案工作时阅读此内容”来引用。所有自动加载的内容都会在每个会话中消耗上下文,永久如此。
- 给颜色赋予角色,而不仅仅是十六进制代码(“主强调色——用于主要 CTA”)。角色是阻止 Claude 在需要颜色时发明一种颜色的东西。直白地陈述规则:任何地方都不能出现品牌套件之外的颜色。否则,来自模板和生成器的非品牌默认颜色会悄悄潜入。
- 两到三个修改前后的语气示例比任何形容词列表更能快速教会语气。
- 如果你的信息传递涉及商业机密,将它加入 gitignore,但仍然从
CLAUDE.md中引用它——这样你就能在不将策略或定价发布到仓库的情况下获得一致的加载。 - 外部同步的品牌文档会过时。 如果语气或受众文档是从共享驱动器复制过来的,在复制之前要重新与源文件核对——营销决策是在对话中做出的,而这些对话永远不会回到文档中。
品牌套件应强制执行的文案纪律:
- 在一个以收集邮件为工作的页面上,永远不要承诺“无需注册/无需邮箱”。 在表单出现之前,它读起来像是减少了摩擦,但随后在需要信任的关键时刻就变成了矛盾。相反,在时间、成本和回报上给予保证——“2 分钟 · 免费 · 结果直接发送到你的邮箱。”
- 每当产品变化时,重新审查安慰性文案。 它会在页面变体之间被复制,并比它所服务的产品活得更久,这恰恰是因为它听起来很有帮助。
- 广告的承诺、页面的承诺和表单的实际要求必须一致。 不匹配会表现为在真相到达的那个步骤出现流失,而不是在不匹配被引入的那个步骤。当一个步骤出现泄漏时,怀疑前一个步骤。
4. 在发布前查看它
两种无需部署就能查看页面的方法。两种都用——它们针对不同的人。
本地开发服务器
供你和 Claude 在构建过程中使用。Claude 可以启动开发服务器,驱动真正的浏览器,截取结果屏幕截图,并读取控制台和网络日志——因此“这个渲染是否正确”是通过查看而不是检查代码来回答的。
- 永远不要同时为同一个项目运行两个开发服务器。 先检查是否有正在运行的进程,然后再启动另一个——特别是当并行代理可能各自启动一个时。
- 将自动重试循环限制在大约 3 次。 一个围绕开发服务器和浏览器自动化的无尽循环“不断重新加载并尝试不同时机直到成功”是真正的资源耗尽风险,而不仅仅是令人烦恼——它曾直接导致机器崩溃。
- 验证清理,而不是相信它。 “我停止了服务器并关闭了标签页”和任何其他未经验证的声明一样——检查进程列表。
- 预料到本地环境会按设计方式与生产环境不同。 任何依赖于真实分析 ID 或实时 API 端点的功能在本地通常是空操作。这是预期行为,不是 bug——将其记录下来,这样就不会每过几周就被重新诊断一次。
- 默认将你的端到端测试指向 localhost,而将它们指向真正的已部署 URL 则是一个刻意的、单独的操作——否则,一次常规测试运行可能会对生产环境执行真实的提交。
Claude Design (claude.ai/design)
供其他人使用。Claude 可以将页面推送到一个 Claude Design 项目中,从而为你提供一个可共享的 URL,客户、设计师或非技术合作伙伴可以在浏览器中直观地编辑文案和布局,无需任何本地设置。这对于页面接入真实站点之前的审批非常有用。
唯一的硬性规则:永远不要盲目写入 Design
在将任何内容写入 Claude Design 项目之前,Claude 必须获取当前的远程版本,进行差异比较,并在覆盖前与你确认。 每次都如此。
Design 端没有版本历史、没有撤销功能,也没有回收站——一个画布文件比一个未跟踪的本地文件更脆弱。盲目覆盖合作者的编辑是永久不可恢复的,并且已经导致整整一个晚上的手写文案流失。
- 将页面创作成自包含的静态 HTML/CSS/JS。 对其中包含 10 个不同的 Claude Design 画布是一个更安全的发布时间表,但一个包含本地图像和 CDN 资产的单文件页面——行得通且可审核——下周必会推向生产环境。
- 在首次构建后的 48 小时内从 Design 迁移到代码仓库。 Design 非常适合反馈和迭代,但稳定版本需要进入仓库。不要编辑已存在的 HTML 文件——编写获取实时页面并将其逐节转换为可审查代码的指令。
- 创建分辨率为 2x 的资源。 设计工具假设视网膜屏幕——1x 资源在清晰度上看起来像是倒退了一步。使用 Claude Design 分配的大小,并生成两倍大小的元素。
- 不要在 Design 中对字体进行子集化。 MDN 的
@font-face字体描述符 (unicode-range) 可以完成这项工作,而且效果更好。向社会稳定更新维护的字体发出请求。
5. 上线后优化
页面上线后,工作便转向数据。这是拥有结构化跟踪和性能预算会带来回报的地方。
你必须拥有的数据
- 页面浏览量和唯一身份访问者——核心指标。没有这个,你什么都不知道。如果这是一个“我们关心访问者是谁”的页面,则还要使用用户 ID。
- 转化事件——表单提交、按钮点击、内容下载。在代码中作为可跟踪事件实现,而不是仅作为页面解析。
- 漏斗步骤——访问者从哪里来,他们看到什么,他们是否转化,他们从哪里离开。记录每一步。
- 页面性能指标——LCP、FID、CLS。使用 Lighthouse CI 或 Web Vitals 库进行跟踪。为每个指标设定一个“红色”阈值,超过该阈值就会触发警报。
在没有 A/B 测试平台的情况下进行测试
- 在跟踪中添加自定义维度和指标。 不要将测试逻辑硬编码到页面中。相反,从 URL 参数或 cookie 中读取变体指定,并将其作为事件属性发送。然后你可以在分析工具中按变体过滤事件。这比迁移 A/B 测试平台更便携。
- 一次只创建一个变体。 同时测试多个变化会在结果中产生噪音。做一个假设,进行更改,衡量效果,然后重复。
- 小批量、频繁地测试。 将测试作为一个拉取请求自然地融入你的版本控制工作流程。合并后,分析工具会自动在新访问者中拆分流量。这比在发现瓶颈几个月后才分析一次要好。
从页面问题中学习
- “页面加载缓慢”很少是“网络连接慢”。 查看浏览器性能工具——如果 JavaScript 总时间 > 2 秒,或图像总大小 > 1MB,那就是资源问题。从那里开始优化。
- 跟踪问题通常是一种实现失误。 “页面浏览跟踪不工作”几乎总是事件代码中的错误,而不是分析平台的问题。使用浏览器的网络选项卡检查分析请求是否被发送。
- “表单未提交”通常意味着 CORS 错误。 检查浏览器控制台是否有被拦截的请求。修复来源白名单问题,而不是表单逻辑。
附录
starters/CLAUDE.md
用于着陆页项目的 CLAUDE.md 的起点。将其放在你仓库的根目录。
# CLAUDE.md
## 规则
- `main` 是生产环境。除非通过你审查并合并的拉取请求,否则不要直接推送到 `main`。
- 在开始任何工作之前,始终就版本号达成一致。版本号由你决定,而不是 Claude。
- 所有工作都在以当前版本命名的功能分支中完成。
- Claude 创建分支、提交并推送,然后为合并到 `main` 提 PR。
- 你在 GitHub 中审查并合并 PR。合并即部署。
- 在开始下一个分支之前,始终将你的本地 `main` 分支更新到最新。
- 所有样式必须使用品牌套件(`brand/` 目录)中的颜色和字体。不允许使用未定义的颜色。
- 在提交包含用户数据处理功能的 PR 之前,始终运行安全审查。
- 在写入 Claude Design 项目之前,始终获取当前的远程版本并比对差异,然后询问。
starters/settings.json
用于 settings.json 的起点,以确保品牌套件在会话开始时加载。
{
"sessionStart": [
"cat brand/brand.md",
"cat docs/architecture.md",
"cat logs/session-latest.md"
]
}
将此文件放在你的项目根目录。根据项目结构调整文件路径。
starters/brand-kit/brand.md
brand/brand.md 的模板。包含你的品牌套件。
# 品牌套件
## 产品
- **产品:** [产品名称]
- **产品:** [一句话产品描述]
- **目标市场:** [目标客户画像]
## 信息传递
- **信息传递策略:** [主要叙述或角度]
- **语气:** [正式/休闲、技术性/可访问性等]
## 视觉规范
- **主色调:** [#HEX](角色:主强调色——用于主要 CTA、链接)
- **次要颜色:** [#HEX](角色:次要强调色——用于悬停、辅助按钮)
- **背景色:** [#HEX](角色:页面背景色)
- **文本颜色:** [#HEX](角色:正文文本)
- **字体:** [字体名称](标题)、[字体名称](正文)
- **Logo:** `images/logo.svg`(首选)、`images/logo.png`(后备)
## 转化
- **主要 CTA:** [主要 CTA 按钮文本]
- **次要 CTA:** [次要 CTA 按钮文本]
- **表单字段:** [字段列表]
- **成功消息:** [表单提交后显示的消息]
## 竞争对手
- **主要竞争对手:** [列表]
- **差异化因素:** [使产品脱颖而出的因素列表]