[{"data":1,"prerenderedAt":836},["ShallowReactive",2],{"chapter-post-project-replication-guide-03-github-and-cloudflare-pages":3},{"chapter":4,"entry":73,"prev":314,"next":701},{"id":5,"title":6,"body":7,"category":55,"cover":52,"date":56,"description":57,"draft":58,"extension":59,"lang":60,"meta":61,"navigation":62,"path":63,"seo":64,"slug":65,"stem":66,"tags":67,"toc":62,"updated":56,"__hash__":72},"chapters/chapters/project-replication-guide.md","零基础完整复刻：Cloudflare 博客项目全流程",{"type":8,"value":9,"toc":51},"minimark",[10,14,17,30,33,45,48],[11,12,13],"p",{},"这个章节是你当前博客项目的“完整复刻手册”。",[11,15,16],{},"目标读者：",[18,19,20,24,27],"ul",{},[21,22,23],"li",{},"没有代码基础",[21,25,26],{},"第一次接触 GitHub、Cloudflare、Nuxt、Decap CMS",[21,28,29],{},"希望照着文档一步步做，最终得到与你当前项目一致的结果",[11,31,32],{},"学习方式建议：",[34,35,36,39,42],"ol",{},[21,37,38],{},"严格按顺序学习，不要跳步骤",[21,40,41],{},"每做完一节就执行“本节验收”",[21,43,44],{},"发现报错先看“常见问题”再继续",[11,46,47],{},"你可以直接从下面目录开始：",[49,50],"chapter-children",{},{"title":52,"searchDepth":53,"depth":53,"links":54},"",2,[],"Chapter","2026-02-14","面向零基础读者的完整项目复刻章节：从准备账号、搭建 Nuxt，到 Pages、Tunnel、CMS、评论、夜间模式与排障。",false,"md","zh-CN",{},true,"/chapters/project-replication-guide",{"title":6,"description":57},"project-replication-guide","chapters/project-replication-guide",[68,69,70,71],"复刻教程","Cloudflare","Nuxt","零基础","T31gU2a4Q3CvJ3Z2B2jyDvX4BtLMmICHnwzpIIudkao",{"id":74,"title":75,"body":76,"category":301,"chapterSlug":65,"cover":52,"date":56,"description":302,"draft":58,"extension":59,"lang":60,"legacySlugs":303,"meta":304,"navigation":62,"order":305,"path":306,"seo":307,"slug":308,"stem":309,"tags":310,"toc":62,"updated":56,"__hash__":313},"chapterPosts/chapter-posts/project-replication-guide/03-github-and-cloudflare-pages.md","第 3 节：连接 GitHub 与 Cloudflare Pages（自动部署主链路）",{"type":8,"value":77,"toc":294},[78,83,91,94,119,122,130,133,137,140,165,169,172,192,195,204,216,220,223,229,232,241,244,252,256,262,276,279,290],[79,80,82],"h2",{"id":81},"_31-先确认代码已在-github","3.1 先确认代码已在 GitHub",[11,84,85,86,90],{},"你的目标仓库是：",[87,88,89],"code",{},"adkeb/blog","。",[11,92,93],{},"本地执行：",[95,96,100],"pre",{"className":97,"code":98,"language":99,"meta":52,"style":52},"language-bash shiki shiki-themes github-light github-dark","git remote -v\n","bash",[87,101,102],{"__ignoreMap":52},[103,104,107,111,115],"span",{"class":105,"line":106},"line",1,[103,108,110],{"class":109},"sScJk","git",[103,112,114],{"class":113},"sZZnC"," remote",[103,116,118],{"class":117},"sj4cs"," -v\n",[11,120,121],{},"应看到：",[95,123,128],{"className":124,"code":126,"language":127,"meta":52},[125],"language-text","origin git@github.com:adkeb/blog.git\n","text",[87,129,126],{"__ignoreMap":52},[11,131,132],{},"如果不是这个地址，先修正 remote 再继续。",[79,134,136],{"id":135},"_32-在-cloudflare-创建-pages-项目","3.2 在 Cloudflare 创建 Pages 项目",[11,138,139],{},"操作路径（新版控制台）：",[34,141,142,148,154,159],{},[21,143,144,145],{},"进入 ",[87,146,147],{},"Workers & Pages",[21,149,150,151],{},"选择 ",[87,152,153],{},"Import an existing Git repository",[21,155,156,157],{},"选择 GitHub 账号与仓库 ",[87,158,89],{},[21,160,161,162],{},"生产分支选 ",[87,163,164],{},"main",[79,166,168],{"id":167},"_33-构建参数必须这样填","3.3 构建参数必须这样填",[11,170,171],{},"这一项非常关键，填错就会失败：",[34,173,174,180,186],{},[21,175,176,177],{},"Framework preset：",[87,178,179],{},"Nuxt.js",[21,181,182,183],{},"Build command：",[87,184,185],{},"npm run generate",[21,187,188,189],{},"Build output directory：",[87,190,191],{},"dist",[11,193,194],{},"你之前踩过的坑：",[18,196,197],{},[21,198,199,200,203],{},"填成 ",[87,201,202],{},".output/public","，会报 “build output directory not found”",[11,205,206,207,210,211,213,214,90],{},"原因：",[87,208,209],{},"nuxt generate"," 产物在 ",[87,212,191],{},"，而不是 ",[87,215,202],{},[79,217,219],{"id":218},"_34-你曾遇到的典型错误是怎么来的","3.4 你曾遇到的典型错误是怎么来的",[11,221,222],{},"报错：",[95,224,227],{"className":225,"code":226,"language":127,"meta":52},[125],"The name 'ASSETS' is reserved in Pages projects.\n",[87,228,226],{"__ignoreMap":52},[11,230,231],{},"本质原因：",[18,233,234],{},[21,235,236,237,240],{},"把 Worker 的 ",[87,238,239],{},"wrangler deploy"," 混进了 Pages 的构建流程",[11,242,243],{},"正确做法：",[34,245,246,249],{},[21,247,248],{},"Pages 只做站点构建与静态发布",[21,250,251],{},"Worker（如 OAuth）单独在本地/CI 用 wrangler 部署",[79,253,255],{"id":254},"_35-验收方法","3.5 验收方法",[11,257,258,259,261],{},"当你 push 到 ",[87,260,164],{}," 后：",[34,263,264,267,270],{},[21,265,266],{},"Cloudflare 自动出现新 deployment",[21,268,269],{},"状态为 Success（绿色）",[21,271,272,275],{},[87,273,274],{},"www.xuyangfly.site"," 可访问",[11,277,278],{},"部署失败时，优先查看：",[18,280,281,284,287],{},[21,282,283],{},"Build command",[21,285,286],{},"Output directory",[21,288,289],{},"是否有额外 deploy 命令误加",[291,292,293],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":52,"searchDepth":53,"depth":53,"links":295},[296,297,298,299,300],{"id":81,"depth":53,"text":82},{"id":135,"depth":53,"text":136},{"id":167,"depth":53,"text":168},{"id":218,"depth":53,"text":219},{"id":254,"depth":53,"text":255},"Guide","把仓库 adkeb/blog 接入 Pages，设置正确构建参数，避开常见部署报错。",[],{},3,"/chapter-posts/project-replication-guide/03-github-and-cloudflare-pages",{"title":75,"description":302},"03-github-and-cloudflare-pages","chapter-posts/project-replication-guide/03-github-and-cloudflare-pages",[68,311,312],"GitHub","Cloudflare Pages","LLAZYoqNkeb-e__OjK3h8vv8ZEdVqyLnVI-RE8JShJ0",{"id":315,"title":316,"body":317,"category":301,"chapterSlug":65,"cover":52,"date":56,"description":691,"draft":58,"extension":59,"lang":60,"legacySlugs":692,"meta":693,"navigation":62,"order":53,"path":694,"seo":695,"slug":696,"stem":697,"tags":698,"toc":62,"updated":56,"__hash__":700},"chapterPosts/chapter-posts/project-replication-guide/02-local-dev-and-nuxt-content.md","第 2 节：本地跑起来（Nuxt + Content + 环境变量）",{"type":8,"value":318,"toc":684},[319,323,326,360,366,369,380,384,390,472,475,495,498,511,515,521,524,563,566,574,577,581,587,607,614,617,634,638,641,664,667,681],[79,320,322],{"id":321},"_21-安装依赖并启动项目","2.1 安装依赖并启动项目",[11,324,325],{},"在项目根目录执行：",[95,327,329],{"className":97,"code":328,"language":99,"meta":52,"style":52},"npm install\ncp .env.example .env\nnpm run dev\n",[87,330,331,339,350],{"__ignoreMap":52},[103,332,333,336],{"class":105,"line":106},[103,334,335],{"class":109},"npm",[103,337,338],{"class":113}," install\n",[103,340,341,344,347],{"class":105,"line":53},[103,342,343],{"class":109},"cp",[103,345,346],{"class":113}," .env.example",[103,348,349],{"class":113}," .env\n",[103,351,352,354,357],{"class":105,"line":305},[103,353,335],{"class":109},[103,355,356],{"class":113}," run",[103,358,359],{"class":113}," dev\n",[11,361,362,363,90],{},"然后打开浏览器：",[87,364,365],{},"http://localhost:3000",[11,367,368],{},"这一步成功，代表：",[34,370,371,374,377],{},[21,372,373],{},"依赖安装正常",[21,375,376],{},"Nuxt 开发服务器可运行",[21,378,379],{},"项目基础代码可读",[79,381,383],{"id":382},"_22-先理解脚本你之后会一直用","2.2 先理解脚本（你之后会一直用）",[11,385,386,389],{},[87,387,388],{},"package.json"," 里的脚本：",[95,391,395],{"className":392,"code":393,"language":394,"meta":52,"style":52},"language-json shiki shiki-themes github-light github-dark","{\n  \"dev\": \"nuxt dev\",\n  \"build\": \"nuxt build\",\n  \"generate\": \"nuxt generate\",\n  \"preview\": \"nuxt preview\",\n  \"check\": \"nuxt typecheck\"\n}\n","json",[87,396,397,403,417,429,442,455,466],{"__ignoreMap":52},[103,398,399],{"class":105,"line":106},[103,400,402],{"class":401},"sVt8B","{\n",[103,404,405,408,411,414],{"class":105,"line":53},[103,406,407],{"class":117},"  \"dev\"",[103,409,410],{"class":401},": ",[103,412,413],{"class":113},"\"nuxt dev\"",[103,415,416],{"class":401},",\n",[103,418,419,422,424,427],{"class":105,"line":305},[103,420,421],{"class":117},"  \"build\"",[103,423,410],{"class":401},[103,425,426],{"class":113},"\"nuxt build\"",[103,428,416],{"class":401},[103,430,432,435,437,440],{"class":105,"line":431},4,[103,433,434],{"class":117},"  \"generate\"",[103,436,410],{"class":401},[103,438,439],{"class":113},"\"nuxt generate\"",[103,441,416],{"class":401},[103,443,445,448,450,453],{"class":105,"line":444},5,[103,446,447],{"class":117},"  \"preview\"",[103,449,410],{"class":401},[103,451,452],{"class":113},"\"nuxt preview\"",[103,454,416],{"class":401},[103,456,458,461,463],{"class":105,"line":457},6,[103,459,460],{"class":117},"  \"check\"",[103,462,410],{"class":401},[103,464,465],{"class":113},"\"nuxt typecheck\"\n",[103,467,469],{"class":105,"line":468},7,[103,470,471],{"class":401},"}\n",[11,473,474],{},"逐条解释：",[34,476,477,483,489],{},[21,478,479,482],{},[87,480,481],{},"dev","：本地开发，改代码会热更新。",[21,484,485,488],{},[87,486,487],{},"generate","：生成静态站（Cloudflare Pages 用这个）。",[21,490,491,494],{},[87,492,493],{},"check","：类型检查，防止明显代码错误。",[11,496,497],{},"你要形成习惯：",[18,499,500,506],{},[21,501,502,503],{},"每次关键改动后跑 ",[87,504,505],{},"npm run check",[21,507,508,509],{},"准备推送前跑 ",[87,510,185],{},[79,512,514],{"id":513},"_23-环境变量为什么这么重要","2.3 环境变量为什么这么重要",[11,516,517,520],{},[87,518,519],{},".env"," 是项目行为总开关。",[11,522,523],{},"你项目中的关键变量：",[34,525,526,536,545,551,557],{},[21,527,528,531,532,535],{},[87,529,530],{},"SITE_URL"," / ",[87,533,534],{},"NUXT_PUBLIC_SITE_URL","：正式站地址",[21,537,538,531,541,544],{},[87,539,540],{},"PREVIEW_URL",[87,542,543],{},"NUXT_PUBLIC_PREVIEW_URL","：预览地址",[21,546,547,550],{},[87,548,549],{},"NUXT_PUBLIC_SHOW_DRAFTS","：是否显示草稿",[21,552,553,556],{},[87,554,555],{},"GISCUS_*","：评论系统配置",[21,558,559,562],{},[87,560,561],{},"CF_ACCESS_AUD","：Cloudflare Access 拓展鉴权字段",[11,564,565],{},"最常见错误：",[18,567,568,571],{},[21,569,570],{},"变量只填了 Production，没填 Preview",[21,572,573],{},"public 与非 public 混用，导致客户端拿不到值",[11,575,576],{},"你的项目已经采用“双写兼容”方式，降低此类风险。",[79,578,580],{"id":579},"_24-内容模型为什么你的文章能变成页面","2.4 内容模型：为什么你的文章能变成页面",[11,582,583,586],{},[87,584,585],{},"content.config.ts"," 定义了 3 套内容集合：",[34,588,589,595,601],{},[21,590,591,594],{},[87,592,593],{},"posts","：普通文章",[21,596,597,600],{},[87,598,599],{},"chapters","：章节父文",[21,602,603,606],{},[87,604,605],{},"chapterPosts","：章节子文章",[11,608,609,610,613],{},"系统会把 Markdown frontmatter 字段（例如 ",[87,611,612],{},"title/date/tags","）解析成可查询数据。",[11,615,616],{},"你看到的页面路由是：",[18,618,619,624,629],{},[21,620,621],{},[87,622,623],{},"/posts/:slug",[21,625,626],{},[87,627,628],{},"/chapters/:chapterSlug",[21,630,631],{},[87,632,633],{},"/chapters/:chapterSlug/:slug",[79,635,637],{"id":636},"_25-本节验收","2.5 本节验收",[11,639,640],{},"执行并确认：",[95,642,644],{"className":97,"code":643,"language":99,"meta":52,"style":52},"npm run check\nnpm run generate\n",[87,645,646,655],{"__ignoreMap":52},[103,647,648,650,652],{"class":105,"line":106},[103,649,335],{"class":109},[103,651,356],{"class":113},[103,653,654],{"class":113}," check\n",[103,656,657,659,661],{"class":105,"line":53},[103,658,335],{"class":109},[103,660,356],{"class":113},[103,662,663],{"class":113}," generate\n",[11,665,666],{},"验收标准：",[34,668,669,672,675],{},[21,670,671],{},"两条命令都通过",[21,673,674],{},"本地页面可正常打开",[21,676,677,678,680],{},"你能看懂 ",[87,679,519],{}," 每个字段大概作用",[291,682,683],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":52,"searchDepth":53,"depth":53,"links":685},[686,687,688,689,690],{"id":321,"depth":53,"text":322},{"id":382,"depth":53,"text":383},{"id":513,"depth":53,"text":514},{"id":579,"depth":53,"text":580},{"id":636,"depth":53,"text":637},"从零启动本地站点，理解 .env、内容模型、页面路由和构建脚本。",[],{},"/chapter-posts/project-replication-guide/02-local-dev-and-nuxt-content",{"title":316,"description":691},"02-local-dev-and-nuxt-content","chapter-posts/project-replication-guide/02-local-dev-and-nuxt-content",[68,70,699],"环境变量","gOmH9AS2UrLEZ73n0vFL9_RNxvaWrYWbSXr6PLbCQWI",{"id":702,"title":703,"body":704,"category":301,"chapterSlug":65,"cover":52,"date":56,"description":825,"draft":58,"extension":59,"lang":60,"legacySlugs":826,"meta":827,"navigation":62,"order":431,"path":828,"seo":829,"slug":830,"stem":831,"tags":832,"toc":62,"updated":56,"__hash__":835},"chapterPosts/chapter-posts/project-replication-guide/04-domain-dns-and-redirect.md","第 4 节：域名、DNS 与 301 跳转（主域统一）",{"type":8,"value":705,"toc":819},[706,710,713,716,727,731,734,760,766,770,773,776,787,791,794,801,804,812],[79,707,709],{"id":708},"_41-为什么要做裸域-301-到-www","4.1 为什么要做裸域 301 到 www",[11,711,712],{},"统一主域可以减少 SEO 分裂和链接重复。",[11,714,715],{},"你的目标是：",[18,717,718],{},[21,719,720,723,724],{},[87,721,722],{},"https://xuyangfly.site/xxx"," 永久跳到 ",[87,725,726],{},"https://www.xuyangfly.site/xxx",[79,728,730],{"id":729},"_42-跳转规则怎么填","4.2 跳转规则怎么填",[11,732,733],{},"在 Cloudflare 中创建转发规则：",[34,735,736,742,748,754],{},[21,737,738,739],{},"URL 匹配：",[87,740,741],{},"xuyangfly.site/*",[21,743,744,745],{},"类型：",[87,746,747],{},"Forwarding URL",[21,749,750,751],{},"状态码：",[87,752,753],{},"301 - Permanent Redirect",[21,755,756,757],{},"目标：",[87,758,759],{},"https://www.xuyangfly.site/$1",[11,761,762,765],{},[87,763,764],{},"$1"," 代表原路径后半段，会被完整保留。",[79,767,769],{"id":768},"_43-为什么你会看到rule-may-not-apply-to-traffic","4.3 为什么你会看到“rule may not apply to traffic”",[11,771,772],{},"这提示表示：当前流量没走 Cloudflare 代理层。",[11,774,775],{},"修复：",[34,777,778,781,784],{},[21,779,780],{},"到 DNS 列表确认根域记录是橙云（Proxied）",[21,782,783],{},"如果没有合适记录，创建一个 A 记录占位并开启代理",[21,785,786],{},"保存后等待 1~5 分钟再测",[79,788,790],{"id":789},"_44-验证命令","4.4 验证命令",[11,792,793],{},"在浏览器访问：",[18,795,796],{},[21,797,798],{},[87,799,800],{},"https://xuyangfly.site/test?a=1",[11,802,803],{},"期望：",[18,805,806],{},[21,807,808,809],{},"地址栏最终变成 ",[87,810,811],{},"https://www.xuyangfly.site/test?a=1",[11,813,814,815,818],{},"如果是连接失败（如 ",[87,816,817],{},"ERR_CONNECTION_CLOSED","），优先回到 DNS 检查代理状态。",{"title":52,"searchDepth":53,"depth":53,"links":820},[821,822,823,824],{"id":708,"depth":53,"text":709},{"id":729,"depth":53,"text":730},{"id":768,"depth":53,"text":769},{"id":789,"depth":53,"text":790},"把裸域 xuyangfly.site 301 到 www，解决规则不生效与代理记录问题。",[],{},"/chapter-posts/project-replication-guide/04-domain-dns-and-redirect",{"title":703,"description":825},"04-domain-dns-and-redirect","chapter-posts/project-replication-guide/04-domain-dns-and-redirect",[68,833,834],"DNS",301,"578oUC4KJGN4YYl6zTyB-MLXMLtuDPxHNbfKQbOntiI",1771232916065]