[{"data":1,"prerenderedAt":786},["ShallowReactive",2],{"chapter-post-project-replication-guide-07-giscus-and-comment-fix":3},{"chapter":4,"entry":73,"prev":270,"next":584},{"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":257,"chapterSlug":65,"cover":52,"date":56,"description":258,"draft":58,"extension":59,"lang":60,"legacySlugs":259,"meta":260,"navigation":62,"order":261,"path":262,"seo":263,"slug":264,"stem":265,"tags":266,"toc":62,"updated":56,"__hash__":269},"chapterPosts/chapter-posts/project-replication-guide/07-giscus-and-comment-fix.md","第 7 节：评论系统 giscus 与空白问题修复",{"type":8,"value":77,"toc":247},[78,83,86,109,116,120,123,131,137,140,148,152,155,166,175,229,233],[79,80,82],"h2",{"id":81},"_71-giscus-必备参数","7.1 giscus 必备参数",[11,84,85],{},"你需要从 giscus 配置页记录：",[34,87,88,94,99,104],{},[21,89,90],{},[91,92,93],"code",{},"repo",[21,95,96],{},[91,97,98],{},"repoId",[21,100,101],{},[91,102,103],{},"category",[21,105,106],{},[91,107,108],{},"categoryId",[11,110,111,112,115],{},"你的当前值是基于仓库 ",[91,113,114],{},"adkeb/blog","。",[79,117,119],{"id":118},"_72-环境变量要在两个环境都填","7.2 环境变量要在两个环境都填",[11,121,122],{},"Cloudflare Pages 里：",[18,124,125,128],{},[21,126,127],{},"Production 环境变量",[21,129,130],{},"Preview 环境变量",[11,132,133,134,115],{},"都要填同样的 ",[91,135,136],{},"GISCUS_*",[11,138,139],{},"否则表现会是：",[18,141,142,145],{},[21,143,144],{},"线上能加载、预览不加载",[21,146,147],{},"或者反过来",[79,149,151],{"id":150},"_73-你遇到的评论空白问题","7.3 你遇到的评论空白问题",[11,153,154],{},"问题现象：",[34,156,157,160,163],{},[21,158,159],{},"登录 GitHub 回来后评论区空白",[21,161,162],{},"刷新当前页面后又空白",[21,164,165],{},"需要手动关弹窗/重进才恢复",[167,168,170,171,174],"h3",{"id":169},"修复点componentsgiscuscommentsclientvue","修复点（",[91,172,173],{},"components/GiscusComments.client.vue","）",[34,176,177,192,203,218],{},[21,178,179,180,183,184,187],{},"监听 ",[91,181,182],{},"focus"," 和 ",[91,185,186],{},"visibilitychange",[18,188,189],{},[21,190,191],{},"从 GitHub 授权窗口返回时，自动重新挂载 giscus。",[21,193,194,195,198],{},"把加载策略改为 ",[91,196,197],{},"eager",[18,199,200],{},[21,201,202],{},"避免懒加载时机导致 iframe 空白。",[21,204,205,206,209,210,213],{},"路由监听从 ",[91,207,208],{},"fullPath"," 收敛到 ",[91,211,212],{},"path",[18,214,215],{},[21,216,217],{},"减少不必要重挂载。",[21,219,220,221,224],{},"主题切换时向 iframe ",[91,222,223],{},"postMessage",[18,225,226],{},[21,227,228],{},"避免夜间模式切换导致评论状态不一致。",[79,230,232],{"id":231},"_74-验收步骤","7.4 验收步骤",[34,234,235,238,241,244],{},[21,236,237],{},"打开任意文章页，确认评论可见。",[21,239,240],{},"点击登录并完成 GitHub 授权。",[21,242,243],{},"回到页面后无需手动刷新即可评论。",[21,245,246],{},"手动刷新页面，评论区仍正常渲染。",{"title":52,"searchDepth":53,"depth":53,"links":248},[249,250,251,256],{"id":81,"depth":53,"text":82},{"id":118,"depth":53,"text":119},{"id":150,"depth":53,"text":151,"children":252},[253],{"id":169,"depth":254,"text":255},3,"修复点（components/GiscusComments.client.vue）",{"id":231,"depth":53,"text":232},"Guide","配置 giscus 参数、环境变量同步，并修复登录后评论空白、刷新后评论空白问题。",[],{},7,"/chapter-posts/project-replication-guide/07-giscus-and-comment-fix",{"title":75,"description":258},"07-giscus-and-comment-fix","chapter-posts/project-replication-guide/07-giscus-and-comment-fix",[68,267,268],"giscus","评论系统","Q3kyHNdaPbn0boCYo_SD58Gnw4JEPaGtjktQD-56xa8",{"id":271,"title":272,"body":273,"category":257,"chapterSlug":65,"cover":52,"date":56,"description":572,"draft":58,"extension":59,"lang":60,"legacySlugs":573,"meta":574,"navigation":62,"order":385,"path":575,"seo":576,"slug":577,"stem":578,"tags":579,"toc":62,"updated":56,"__hash__":583},"chapterPosts/chapter-posts/project-replication-guide/06-decap-cms-and-oauth-worker.md","第 6 节：Decap CMS 与 GitHub OAuth Worker",{"type":8,"value":274,"toc":564},[275,279,286,289,306,309,313,318,394,398,404,421,424,462,473,477,483,497,500,504,536,539,543,560],[79,276,278],{"id":277},"_61-为什么要单独部署-oauth-worker","6.1 为什么要单独部署 OAuth Worker",[11,280,281,282,285],{},"你遇到过默认 Netlify OAuth 回调不可用问题（",[91,283,284],{},"Not Found","）。",[11,287,288],{},"因此项目采用自建方案：",[18,290,291,297],{},[21,292,293,296],{},[91,294,295],{},"ops/decap-oauth/worker.js"," 处理 GitHub OAuth",[21,298,299,302,303],{},[91,300,301],{},"public/admin/config.yml"," 指向你自己的 ",[91,304,305],{},"base_url",[11,307,308],{},"这让登录链路完全可控。",[79,310,312],{"id":311},"_62-cms-配置必须与项目一致","6.2 CMS 配置（必须与项目一致）",[11,314,315,317],{},[91,316,301],{}," 核心段：",[319,320,324],"pre",{"className":321,"code":322,"language":323,"meta":52,"style":52},"language-yaml shiki shiki-themes github-light github-dark","backend:\n  name: github\n  repo: adkeb/blog\n  branch: main\n  base_url: https://decap-github-oauth.xuyang020128.workers.dev\n  auth_endpoint: auth\n","yaml",[91,325,326,339,351,361,372,383],{"__ignoreMap":52},[327,328,331,335],"span",{"class":329,"line":330},"line",1,[327,332,334],{"class":333},"s9eBZ","backend",[327,336,338],{"class":337},"sVt8B",":\n",[327,340,341,344,347],{"class":329,"line":53},[327,342,343],{"class":333},"  name",[327,345,346],{"class":337},": ",[327,348,350],{"class":349},"sZZnC","github\n",[327,352,353,356,358],{"class":329,"line":254},[327,354,355],{"class":333},"  repo",[327,357,346],{"class":337},[327,359,360],{"class":349},"adkeb/blog\n",[327,362,364,367,369],{"class":329,"line":363},4,[327,365,366],{"class":333},"  branch",[327,368,346],{"class":337},[327,370,371],{"class":349},"main\n",[327,373,375,378,380],{"class":329,"line":374},5,[327,376,377],{"class":333},"  base_url",[327,379,346],{"class":337},[327,381,382],{"class":349},"https://decap-github-oauth.xuyang020128.workers.dev\n",[327,384,386,389,391],{"class":329,"line":385},6,[327,387,388],{"class":333},"  auth_endpoint",[327,390,346],{"class":337},[327,392,393],{"class":349},"auth\n",[79,395,397],{"id":396},"_63-worker-环境变量与密钥","6.3 Worker 环境变量与密钥",[11,399,400,403],{},[91,401,402],{},"ops/decap-oauth/wrangler.toml"," 里是公开配置：",[18,405,406,411,416],{},[21,407,408],{},[91,409,410],{},"CMS_ORIGIN",[21,412,413],{},[91,414,415],{},"GITHUB_REDIRECT_URI",[21,417,418],{},[91,419,420],{},"GITHUB_CLIENT_ID",[11,422,423],{},"密钥必须用 secret：",[319,425,429],{"className":426,"code":427,"language":428,"meta":52,"style":52},"language-bash shiki shiki-themes github-light github-dark","npx wrangler secret put GITHUB_CLIENT_SECRET\nnpx wrangler secret put OAUTH_STATE_SECRET\n","bash",[91,430,431,449],{"__ignoreMap":52},[327,432,433,437,440,443,446],{"class":329,"line":330},[327,434,436],{"class":435},"sScJk","npx",[327,438,439],{"class":349}," wrangler",[327,441,442],{"class":349}," secret",[327,444,445],{"class":349}," put",[327,447,448],{"class":349}," GITHUB_CLIENT_SECRET\n",[327,450,451,453,455,457,459],{"class":329,"line":53},[327,452,436],{"class":435},[327,454,439],{"class":349},[327,456,442],{"class":349},[327,458,445],{"class":349},[327,460,461],{"class":349}," OAUTH_STATE_SECRET\n",[11,463,464,468,469,472],{},[465,466,467],"strong",{},"注意","：",[91,470,471],{},"GITHUB_CLIENT_SECRET"," 绝对不能写入 git。",[79,474,476],{"id":475},"_64-worker-路由逻辑读懂就够不用会写","6.4 Worker 路由逻辑（读懂就够，不用会写）",[11,478,479,482],{},[91,480,481],{},"worker.js"," 做两件事：",[34,484,485,491],{},[21,486,487,490],{},[91,488,489],{},"/auth","：发起 GitHub 授权",[21,492,493,496],{},[91,494,495],{},"/callback","：换 token 并回传给 Decap 窗口",[11,498,499],{},"你项目中还做了弹窗握手与 postMessage 回传，解决了“登录成功但 CMS 不更新”的常见问题。",[79,501,503],{"id":502},"_65-部署命令完整","6.5 部署命令（完整）",[319,505,507],{"className":426,"code":506,"language":428,"meta":52,"style":52},"cd ops/decap-oauth\nnpx wrangler whoami\nnpx wrangler deploy\n",[91,508,509,518,527],{"__ignoreMap":52},[327,510,511,515],{"class":329,"line":330},[327,512,514],{"class":513},"sj4cs","cd",[327,516,517],{"class":349}," ops/decap-oauth\n",[327,519,520,522,524],{"class":329,"line":53},[327,521,436],{"class":435},[327,523,439],{"class":349},[327,525,526],{"class":349}," whoami\n",[327,528,529,531,533],{"class":329,"line":254},[327,530,436],{"class":435},[327,532,439],{"class":349},[327,534,535],{"class":349}," deploy\n",[11,537,538],{},"部署成功会返回你的 workers.dev 地址。",[79,540,542],{"id":541},"_66-验收标准","6.6 验收标准",[34,544,545,551,554,557],{},[21,546,547,548],{},"打开 ",[91,549,550],{},"https://www.xuyangfly.site/admin",[21,552,553],{},"点“使用 GitHub 登录”",[21,555,556],{},"授权后可进入 CMS 内容列表",[21,558,559],{},"新建文章后能触发 Git 提交",[561,562,563],"style",{},"html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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 .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":52,"searchDepth":53,"depth":53,"links":565},[566,567,568,569,570,571],{"id":277,"depth":53,"text":278},{"id":311,"depth":53,"text":312},{"id":396,"depth":53,"text":397},{"id":475,"depth":53,"text":476},{"id":502,"depth":53,"text":503},{"id":541,"depth":53,"text":542},"从 Netlify 失败场景迁移到 Cloudflare Worker OAuth 网关，打通 /admin 可视化编辑。",[],{},"/chapter-posts/project-replication-guide/06-decap-cms-and-oauth-worker",{"title":272,"description":572},"06-decap-cms-and-oauth-worker","chapter-posts/project-replication-guide/06-decap-cms-and-oauth-worker",[68,580,581,582],"Decap CMS","OAuth","Worker","CftJ87f8FswywDArDHUTg3sgFZwMb6KyNdd-iw7FgN8",{"id":585,"title":586,"body":587,"category":257,"chapterSlug":65,"cover":52,"date":56,"description":774,"draft":58,"extension":59,"lang":60,"legacySlugs":775,"meta":776,"navigation":62,"order":777,"path":778,"seo":779,"slug":780,"stem":781,"tags":782,"toc":62,"updated":56,"__hash__":785},"chapterPosts/chapter-posts/project-replication-guide/08-chapter-system-and-route-migration.md","第 8 节：章节体系（父文 + 子文 + 旧链接 301）",{"type":8,"value":588,"toc":767},[589,593,596,616,619,636,640,646,654,657,671,674,678,681,697,708,712,719,735,738,742,745,753,756,764],[79,590,592],{"id":591},"_81-章节体系是什么","8.1 章节体系是什么",[11,594,595],{},"你当前项目有 3 类内容：",[34,597,598,604,610],{},[21,599,600,601],{},"普通文章 ",[91,602,603],{},"posts",[21,605,606,607],{},"章节父文 ",[91,608,609],{},"chapters",[21,611,612,613],{},"章节子文章 ",[91,614,615],{},"chapterPosts",[11,617,618],{},"路由分别是：",[18,620,621,626,631],{},[21,622,623],{},[91,624,625],{},"/posts/:slug",[21,627,628],{},[91,629,630],{},"/chapters/:chapterSlug",[21,632,633],{},[91,634,635],{},"/chapters/:chapterSlug/:slug",[79,637,639],{"id":638},"_82-目录约束为什么重要","8.2 目录约束为什么重要",[11,641,642,643,468],{},"子文章文件路径必须匹配 frontmatter 的 ",[91,644,645],{},"chapterSlug",[319,647,652],{"className":648,"code":650,"language":651,"meta":52},[649],"language-text","content/chapter-posts/\u003CchapterSlug>/\u003Cpost>.md\n","text",[91,653,650],{"__ignoreMap":52},[11,655,656],{},"比如：",[18,658,659,665],{},[21,660,661,662],{},"路径：",[91,663,664],{},"content/chapter-posts/machine-learning/linear-regression.md",[21,666,667,668],{},"frontmatter：",[91,669,670],{},"chapterSlug: machine-learning",[11,672,673],{},"如果不一致，构建阶段直接报错，阻止脏数据上线。",[79,675,677],{"id":676},"_83-章节正文插目录占位符","8.3 章节正文插目录占位符",[11,679,680],{},"章节正文里插入：",[319,682,685],{"className":683,"code":684,"language":59,"meta":52,"style":52},"language-md shiki shiki-themes github-light github-dark","::chapter-children\n::\n",[91,686,687,692],{"__ignoreMap":52},[327,688,689],{"class":329,"line":330},[327,690,691],{"class":337},"::chapter-children\n",[327,693,694],{"class":329,"line":53},[327,695,696],{"class":337},"::\n",[11,698,699,700,703,704,707],{},"渲染时会由 ",[91,701,702],{},"components/content/ChapterChildren.vue"," 自动拉取同章节子文章并按 ",[91,705,706],{},"order"," 排序。",[79,709,711],{"id":710},"_84-旧链接迁移301","8.4 旧链接迁移（301）",[11,713,714,715,718],{},"当历史链接还是 ",[91,716,717],{},"/posts/old-slug"," 时，系统会：",[34,720,721,724,730],{},[21,722,723],{},"先查普通文章",[21,725,726,727],{},"查不到再查章节子文章的 ",[91,728,729],{},"legacySlugs",[21,731,732,733],{},"命中则 301 到新地址 ",[91,734,635],{},[11,736,737],{},"这样迁移不会让旧外链失效。",[79,739,741],{"id":740},"_85-当前策略子文章只在章节体系内出现","8.5 当前策略：子文章只在章节体系内出现",[11,743,744],{},"根据你的新要求，项目已调整为：",[18,746,747,750],{},[21,748,749],{},"子文章不进入首页、全站列表、标签页等全局流",[21,751,752],{},"子文章只通过章节页目录进入",[11,754,755],{},"这让信息结构更清晰：",[18,757,758,761],{},[21,759,760],{},"首页展示“文章/章节”",[21,762,763],{},"深度内容在章节内展开",[561,765,766],{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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":768},[769,770,771,772,773],{"id":591,"depth":53,"text":592},{"id":638,"depth":53,"text":639},{"id":676,"depth":53,"text":677},{"id":710,"depth":53,"text":711},{"id":740,"depth":53,"text":741},"实现章节化写作、章节目录占位符、子文章路由与 legacySlugs 迁移跳转。",[],{},8,"/chapter-posts/project-replication-guide/08-chapter-system-and-route-migration",{"title":586,"description":774},"08-chapter-system-and-route-migration","chapter-posts/project-replication-guide/08-chapter-system-and-route-migration",[68,783,784],"章节体系","路由迁移","09lBKEy9m61KQ_TiC-FjEgHv0NK9QVPQjZPYyqfn_v0",1771232916066]