[{"data":1,"prerenderedAt":949},["ShallowReactive",2],{"notes-seo-completion-and-generate-hook":3},{"id":4,"title":5,"body":6,"category":938,"date":939,"description":940,"extension":941,"meta":942,"navigation":607,"order":938,"path":943,"seo":944,"seoDescription":940,"seoTitle":945,"slug":946,"stem":947,"__hash__":948},"notes\u002Fnotes\u002F2026-05-09-seo-completion-and-generate-hook.md","SEO 缺失项补全与 generate 产物自动同步",{"type":7,"value":8,"toc":920},"minimark",[9,16,20,45,49,53,184,188,222,226,232,239,352,358,486,490,497,523,545,549,561,691,695,699,710,714,723,844,847,881,884,916],[10,11,12],"blockquote",{},[13,14,15],"p",{},"记录时间：2026-05-09",[17,18,19],"h2",{"id":19},"问题",[21,22,23,27,30],"ol",{},[24,25,26],"li",{},"梳理本站 SEO 关键词分布在哪些地方",[24,28,29],{},"将分析出的 SEO 缺失项全部实现（keywords、Twitter Card、JSON-LD、ogImage、全局默认 meta、面包屑 Schema）",[24,31,32,33,37,38,41,42],{},"每次 ",[34,35,36],"code",{},"npm run generate"," 后自动将 ",[34,39,40],{},".output\u002Fpublic\u002F"," 复制到部署仓库 ",[34,43,44],{},"mental-model-public\u002F",[17,46,48],{"id":47},"seo-关键词分布分析","SEO 关键词分布分析",[50,51,52],"h3",{"id":52},"现有分布层级",[54,55,56,72],"table",{},[57,58,59],"thead",{},[60,61,62,66,69],"tr",{},[63,64,65],"th",{},"层级",[63,67,68],{},"位置",[63,70,71],{},"内容",[73,74,75,92,113,132,152,165],"tbody",{},[60,76,77,81,86],{},[78,79,80],"td",{},"全局配置",[78,82,83],{},[34,84,85],{},"nuxt.config.ts",[78,87,88,91],{},[34,89,90],{},"lang: zh-CN","、favicon、字体预加载",[60,93,94,97,102],{},[78,95,96],{},"内容 Schema",[78,98,99],{},[34,100,101],{},"content.config.ts",[78,103,104,105,108,109,112],{},"定义 ",[34,106,107],{},"seoTitle"," \u002F ",[34,110,111],{},"seoDescription"," 字段",[60,114,115,118,123],{},[78,116,117],{},"Markdown frontmatter",[78,119,120],{},[34,121,122],{},"content\u002F**\u002F*.md",[78,124,125,126,128,129,131],{},"每篇文章的 ",[34,127,107],{}," + ",[34,130,111],{},"（关键词最密集）",[60,133,134,137,142],{},[78,135,136],{},"静态页面",[78,138,139],{},[34,140,141],{},"pages\u002F*.vue",[78,143,144,145,108,148,151],{},"硬编码 ",[34,146,147],{},"title",[34,149,150],{},"description"," \u002F OG 标签",[60,153,154,157,162],{},[78,155,156],{},"Composable",[78,158,159],{},[34,160,161],{},"useArticlePage.ts",[78,163,164],{},"动态文章页的 SEO 复用逻辑",[60,166,167,170,175],{},[78,168,169],{},"服务端路由",[78,171,172],{},[34,173,174],{},"server\u002Froutes\u002F",[78,176,177,108,180,183],{},[34,178,179],{},"sitemap.xml",[34,181,182],{},"robots.txt"," 动态生成",[50,185,187],{"id":186},"缺失项改动前","缺失项（改动前）",[189,190,191,197,204,207,212,219],"ul",{},[24,192,193,196],{},[34,194,195],{},"\u003Cmeta name=\"keywords\">"," — 未设置",[24,198,199,200,203],{},"Twitter Card (",[34,201,202],{},"twitter:card",") — 未设置",[24,205,206],{},"JSON-LD 结构化数据 — 未实现",[24,208,209,196],{},[34,210,211],{},"ogImage",[24,213,214,215,108,217,196],{},"全局默认 ",[34,216,147],{},[34,218,150],{},[24,220,221],{},"面包屑 BreadcrumbList Schema — 未实现",[17,223,225],{"id":224},"seo-缺失项实现","SEO 缺失项实现",[50,227,229,230],{"id":228},"全局配置-nuxtconfigts","全局配置 — ",[34,231,85],{},[13,233,234,235,238],{},"在 ",[34,236,237],{},"app.head.meta"," 中添加：",[240,241,246],"pre",{"className":242,"code":243,"language":244,"meta":245,"style":245},"language-ts shiki shiki-themes github-light github-dark","{ name: 'keywords', content: '段永平,大道,芒格,查理芒格,巴菲特,价值投资,安全边际,商业模式,生意模式,企业文化,管理层,价值观,能力圈' },\n{ name: 'description', content: '整理跨学科思维模型，用普通读者能理解的方式解释判断、决策、系统和心理误判。' },\n{ property: 'og:site_name', content: '多元思维模型' },\n{ property: 'og:locale', content: 'zh_CN' },\n","ts","",[34,247,248,282,305,329],{"__ignoreMap":245},[249,250,253,257,261,264,268,271,274,276,279],"span",{"class":251,"line":252},"line",1,[249,254,256],{"class":255},"sVt8B","{ ",[249,258,260],{"class":259},"sScJk","name",[249,262,263],{"class":255},": ",[249,265,267],{"class":266},"sZZnC","'keywords'",[249,269,270],{"class":255},", ",[249,272,273],{"class":259},"content",[249,275,263],{"class":255},[249,277,278],{"class":266},"'段永平,大道,芒格,查理芒格,巴菲特,价值投资,安全边际,商业模式,生意模式,企业文化,管理层,价值观,能力圈'",[249,280,281],{"class":255}," },\n",[249,283,285,287,289,291,294,296,298,300,303],{"class":251,"line":284},2,[249,286,256],{"class":255},[249,288,260],{"class":259},[249,290,263],{"class":255},[249,292,293],{"class":266},"'description'",[249,295,270],{"class":255},[249,297,273],{"class":259},[249,299,263],{"class":255},[249,301,302],{"class":266},"'整理跨学科思维模型，用普通读者能理解的方式解释判断、决策、系统和心理误判。'",[249,304,281],{"class":255},[249,306,308,310,313,315,318,320,322,324,327],{"class":251,"line":307},3,[249,309,256],{"class":255},[249,311,312],{"class":259},"property",[249,314,263],{"class":255},[249,316,317],{"class":266},"'og:site_name'",[249,319,270],{"class":255},[249,321,273],{"class":259},[249,323,263],{"class":255},[249,325,326],{"class":266},"'多元思维模型'",[249,328,281],{"class":255},[249,330,332,334,336,338,341,343,345,347,350],{"class":251,"line":331},4,[249,333,256],{"class":255},[249,335,312],{"class":259},[249,337,263],{"class":255},[249,339,340],{"class":266},"'og:locale'",[249,342,270],{"class":255},[249,344,273],{"class":259},[249,346,263],{"class":255},[249,348,349],{"class":266},"'zh_CN'",[249,351,281],{"class":255},[13,353,234,354,357],{},[34,355,356],{},"app.head.script"," 中添加 WebSite JSON-LD：",[240,359,361],{"className":242,"code":360,"language":244,"meta":245,"style":245},"{\n  type: 'application\u002Fld+json',\n  innerHTML: JSON.stringify({\n    '@context': 'https:\u002F\u002Fschema.org',\n    '@type': 'WebSite',\n    name: '多元思维模型',\n    url: process.env.NUXT_PUBLIC_SITE_URL || 'https:\u002F\u002Fmunger-models.example.com',\n    description: '整理跨学科思维模型…',\n    inLanguage: 'zh-CN'\n  })\n}\n",[34,362,363,368,381,401,413,426,436,454,465,474,480],{"__ignoreMap":245},[249,364,365],{"class":251,"line":252},[249,366,367],{"class":255},"{\n",[249,369,370,373,375,378],{"class":251,"line":284},[249,371,372],{"class":259},"  type",[249,374,263],{"class":255},[249,376,377],{"class":266},"'application\u002Fld+json'",[249,379,380],{"class":255},",\n",[249,382,383,386,388,392,395,398],{"class":251,"line":307},[249,384,385],{"class":259},"  innerHTML",[249,387,263],{"class":255},[249,389,391],{"class":390},"sj4cs","JSON",[249,393,394],{"class":255},".",[249,396,397],{"class":259},"stringify",[249,399,400],{"class":255},"({\n",[249,402,403,406,408,411],{"class":251,"line":331},[249,404,405],{"class":266},"    '@context'",[249,407,263],{"class":255},[249,409,410],{"class":266},"'https:\u002F\u002Fschema.org'",[249,412,380],{"class":255},[249,414,416,419,421,424],{"class":251,"line":415},5,[249,417,418],{"class":266},"    '@type'",[249,420,263],{"class":255},[249,422,423],{"class":266},"'WebSite'",[249,425,380],{"class":255},[249,427,429,432,434],{"class":251,"line":428},6,[249,430,431],{"class":255},"    name: ",[249,433,326],{"class":266},[249,435,380],{"class":255},[249,437,439,442,445,449,452],{"class":251,"line":438},7,[249,440,441],{"class":255},"    url: process.env.",[249,443,444],{"class":390},"NUXT_PUBLIC_SITE_URL",[249,446,448],{"class":447},"szBVR"," ||",[249,450,451],{"class":266}," 'https:\u002F\u002Fmunger-models.example.com'",[249,453,380],{"class":255},[249,455,457,460,463],{"class":251,"line":456},8,[249,458,459],{"class":255},"    description: ",[249,461,462],{"class":266},"'整理跨学科思维模型…'",[249,464,380],{"class":255},[249,466,468,471],{"class":251,"line":467},9,[249,469,470],{"class":255},"    inLanguage: ",[249,472,473],{"class":266},"'zh-CN'\n",[249,475,477],{"class":251,"line":476},10,[249,478,479],{"class":255},"  })\n",[249,481,483],{"class":251,"line":482},11,[249,484,485],{"class":255},"}\n",[50,487,489],{"id":488},"页面级-twitter-card-ogimage","页面级 — Twitter Card + ogImage",[13,491,492,493,496],{},"所有页面的 ",[34,494,495],{},"useSeoMeta()"," 追加两个字段：",[240,498,500],{"className":242,"code":499,"language":244,"meta":245,"style":245},"twitterCard: 'summary',\nogImage: '\u002Fog-image.png'\n",[34,501,502,514],{"__ignoreMap":245},[249,503,504,507,509,512],{"class":251,"line":252},[249,505,506],{"class":259},"twitterCard",[249,508,263],{"class":255},[249,510,511],{"class":266},"'summary'",[249,513,380],{"class":255},[249,515,516,518,520],{"class":251,"line":284},[249,517,211],{"class":259},[249,519,263],{"class":255},[249,521,522],{"class":266},"'\u002Fog-image.png'\n",[13,524,525,526,529,530,529,533,529,536,529,539,529,542,544],{},"涉及 6 处：",[34,527,528],{},"index.vue","、",[34,531,532],{},"library\u002Findex.vue",[34,534,535],{},"notes\u002Findex.vue",[34,537,538],{},"about.vue",[34,540,541],{},"library\u002F[slug].vue",[34,543,161],{},"。",[50,546,548],{"id":547},"文章页-article-breadcrumblist-json-ld","文章页 — Article + BreadcrumbList JSON-LD",[13,550,234,551,553,554,556,557,560],{},[34,552,541],{}," 和 ",[34,555,161],{}," 的 ",[34,558,559],{},"useHead()"," 中注入两段结构化数据：",[240,562,564],{"className":242,"code":563,"language":244,"meta":245,"style":245},"\u002F\u002F Article schema\n{ '@type': 'Article', headline: title, description, url, inLanguage: 'zh-CN' }\n\n\u002F\u002F BreadcrumbList schema\n{ '@type': 'BreadcrumbList', itemListElement: [\n  { position: 1, name: '首页', item: siteUrl },\n  { position: 2, name: '价值投资', item: `${siteUrl}\u002Flibrary` },\n  { position: 3, name: page.title }\n]}\n",[34,565,566,572,603,609,614,633,650,676,686],{"__ignoreMap":245},[249,567,568],{"class":251,"line":252},[249,569,571],{"class":570},"sJ8bj","\u002F\u002F Article schema\n",[249,573,574,576,579,581,584,586,589,592,595,597,600],{"class":251,"line":284},[249,575,256],{"class":255},[249,577,578],{"class":266},"'@type'",[249,580,263],{"class":255},[249,582,583],{"class":266},"'Article'",[249,585,270],{"class":255},[249,587,588],{"class":259},"headline",[249,590,591],{"class":255},": title, description, url, ",[249,593,594],{"class":259},"inLanguage",[249,596,263],{"class":255},[249,598,599],{"class":266},"'zh-CN'",[249,601,602],{"class":255}," }\n",[249,604,605],{"class":251,"line":307},[249,606,608],{"emptyLinePlaceholder":607},true,"\n",[249,610,611],{"class":251,"line":331},[249,612,613],{"class":570},"\u002F\u002F BreadcrumbList schema\n",[249,615,616,618,620,622,625,627,630],{"class":251,"line":415},[249,617,256],{"class":255},[249,619,578],{"class":266},[249,621,263],{"class":255},[249,623,624],{"class":266},"'BreadcrumbList'",[249,626,270],{"class":255},[249,628,629],{"class":259},"itemListElement",[249,631,632],{"class":255},": [\n",[249,634,635,638,641,644,647],{"class":251,"line":428},[249,636,637],{"class":255},"  { position: ",[249,639,640],{"class":390},"1",[249,642,643],{"class":255},", name: ",[249,645,646],{"class":266},"'首页'",[249,648,649],{"class":255},", item: siteUrl },\n",[249,651,652,654,657,659,662,665,668,671,674],{"class":251,"line":438},[249,653,637],{"class":255},[249,655,656],{"class":390},"2",[249,658,643],{"class":255},[249,660,661],{"class":266},"'价值投资'",[249,663,664],{"class":255},", item: ",[249,666,667],{"class":266},"`${",[249,669,670],{"class":255},"siteUrl",[249,672,673],{"class":266},"}\u002Flibrary`",[249,675,281],{"class":255},[249,677,678,680,683],{"class":251,"line":456},[249,679,637],{"class":255},[249,681,682],{"class":390},"3",[249,684,685],{"class":255},", name: page.title }\n",[249,687,688],{"class":251,"line":467},[249,689,690],{"class":255},"]}\n",[17,692,694],{"id":693},"generate-产物自动同步","generate 产物自动同步",[50,696,698],{"id":697},"claude-code-plan-文件存储位置","Claude Code Plan 文件存储位置",[13,700,701,702,705,706,709],{},"Plan 文件保存在用户主目录 ",[34,703,704],{},"~\u002F.claude\u002Fplans\u002F"," 下（全局），不在项目的 ",[34,707,708],{},".claude\u002F"," 中。如需保留某次 plan，可手动复制到项目目录。",[50,711,713],{"id":712},"posttooluse-hook-配置","PostToolUse Hook 配置",[13,715,234,716,719,720,722],{},[34,717,718],{},".claude\u002Fsettings.local.json"," 中添加 hook，在 ",[34,721,36],{}," 完成后自动 rsync：",[240,724,728],{"className":725,"code":726,"language":727,"meta":245,"style":245},"language-json shiki shiki-themes github-light github-dark","{\n  \"hooks\": {\n    \"PostToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"cmd=$(jq -r '.tool_input.command' 2>\u002Fdev\u002Fnull); if echo \\\"$cmd\\\" | grep -q 'npm run generate'; then rsync -a --delete .output\u002Fpublic\u002F \u002FUsers\u002Fruimin\u002FDesktop\u002Fcode\u002Fmental-model-public\u002F; fi\"\n          }\n        ]\n      }\n    ]\n  }\n}\n","json",[34,729,730,734,742,749,754,766,773,778,790,811,816,821,827,833,839],{"__ignoreMap":245},[249,731,732],{"class":251,"line":252},[249,733,367],{"class":255},[249,735,736,739],{"class":251,"line":284},[249,737,738],{"class":390},"  \"hooks\"",[249,740,741],{"class":255},": {\n",[249,743,744,747],{"class":251,"line":307},[249,745,746],{"class":390},"    \"PostToolUse\"",[249,748,632],{"class":255},[249,750,751],{"class":251,"line":331},[249,752,753],{"class":255},"      {\n",[249,755,756,759,761,764],{"class":251,"line":415},[249,757,758],{"class":390},"        \"matcher\"",[249,760,263],{"class":255},[249,762,763],{"class":266},"\"Bash\"",[249,765,380],{"class":255},[249,767,768,771],{"class":251,"line":428},[249,769,770],{"class":390},"        \"hooks\"",[249,772,632],{"class":255},[249,774,775],{"class":251,"line":438},[249,776,777],{"class":255},"          {\n",[249,779,780,783,785,788],{"class":251,"line":456},[249,781,782],{"class":390},"            \"type\"",[249,784,263],{"class":255},[249,786,787],{"class":266},"\"command\"",[249,789,380],{"class":255},[249,791,792,795,797,800,803,806,808],{"class":251,"line":467},[249,793,794],{"class":390},"            \"command\"",[249,796,263],{"class":255},[249,798,799],{"class":266},"\"cmd=$(jq -r '.tool_input.command' 2>\u002Fdev\u002Fnull); if echo ",[249,801,802],{"class":390},"\\\"",[249,804,805],{"class":266},"$cmd",[249,807,802],{"class":390},[249,809,810],{"class":266}," | grep -q 'npm run generate'; then rsync -a --delete .output\u002Fpublic\u002F \u002FUsers\u002Fruimin\u002FDesktop\u002Fcode\u002Fmental-model-public\u002F; fi\"\n",[249,812,813],{"class":251,"line":476},[249,814,815],{"class":255},"          }\n",[249,817,818],{"class":251,"line":482},[249,819,820],{"class":255},"        ]\n",[249,822,824],{"class":251,"line":823},12,[249,825,826],{"class":255},"      }\n",[249,828,830],{"class":251,"line":829},13,[249,831,832],{"class":255},"    ]\n",[249,834,836],{"class":251,"line":835},14,[249,837,838],{"class":255},"  }\n",[249,840,842],{"class":251,"line":841},15,[249,843,485],{"class":255},[13,845,846],{},"关键点：",[189,848,849,861,875],{},[24,850,851,852,856,857,860],{},"Hook 的输入通过 ",[853,854,855],"strong",{},"stdin JSON"," 传递，不是环境变量，需要用 ",[34,858,859],{},"jq"," 解析",[24,862,863,866,867,870,871,874],{},[34,864,865],{},"rsync -a --delete"," 完整同步，但不会删除目标目录的 ",[34,868,869],{},".git\u002F","（因为源目录没有 ",[34,872,873],{},".git","）",[24,876,877,880],{},[34,878,879],{},"matcher: \"Bash\""," 仅匹配 Bash 工具调用",[17,882,883],{"id":883},"小结",[189,885,886,897,900,911],{},[24,887,888,889,108,891,893,894,896],{},"SEO 关键词主要分布在 Markdown frontmatter（",[34,890,107],{},[34,892,111],{},"）和各页面的 ",[34,895,495],{}," 中",[24,898,899],{},"补全后新增了全局 keywords、Twitter Card、ogImage、WebSite\u002FArticle\u002FBreadcrumbList JSON-LD",[24,901,902,903,906,907,910],{},"需要在 ",[34,904,905],{},"public\u002F"," 下放置 ",[34,908,909],{},"og-image.png","（1200×630）供社交分享使用",[24,912,913,914,860],{},"Claude Code hook 使用 stdin JSON 传递工具输入，配置时需用 ",[34,915,859],{},[917,918,919],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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 .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":245,"searchDepth":284,"depth":284,"links":921},[922,923,927,933,937],{"id":19,"depth":284,"text":19},{"id":47,"depth":284,"text":48,"children":924},[925,926],{"id":52,"depth":307,"text":52},{"id":186,"depth":307,"text":187},{"id":224,"depth":284,"text":225,"children":928},[929,931,932],{"id":228,"depth":307,"text":930},"全局配置 — nuxt.config.ts",{"id":488,"depth":307,"text":489},{"id":547,"depth":307,"text":548},{"id":693,"depth":284,"text":694,"children":934},[935,936],{"id":697,"depth":307,"text":698},{"id":712,"depth":307,"text":713},{"id":883,"depth":284,"text":883},null,"2026-05-09 00:00:00 CST","梳理网站 SEO 关键词分布，补全 meta keywords、Twitter Card、JSON-LD 结构化数据等缺失项，并配置 PostToolUse hook 实现 generate 后自动同步产物。","md",{},"\u002Fnotes\u002F2026-05-09-seo-completion-and-generate-hook",{"title":5,"description":940},"SEO 缺失项补全与 generate 产物自动同步｜个人笔记","seo-completion-and-generate-hook","notes\u002F2026-05-09-seo-completion-and-generate-hook","NlCiqwuGQtKOPgRz9SbwkHh4BITH8BbEeMaTtIe3yVk",1781774044767]