[{"data":1,"prerenderedAt":2883},["ShallowReactive",2],{"content-/search-console-404-investigation":3,"all-pages-for-dir":2860,"related-/search-console-404-investigation":2861,"og-image-/search-console-404-investigation":2882},{"id":4,"title":5,"body":6,"category":2845,"concepts":2845,"description":2846,"extension":2847,"meta":2848,"navigation":310,"ogImage":2845,"path":2849,"project_name":2845,"published":2850,"publishedAt":2851,"seo":2852,"stem":2853,"tags":2854,"todo":2845,"unpublished":2850,"updatedAt":2851,"__hash__":2859},"pages/2025-12/2025-12-18/search-console-404-investigation.md","Google Search Console 404エラー調査",{"type":7,"value":8,"toc":2799},"minimark",[9,13,17,21,38,42,46,49,60,63,74,78,84,87,159,174,177,183,187,190,193,199,202,222,226,229,235,238,244,248,252,255,258,262,706,714,719,846,851,1063,1067,1071,1154,1159,1165,1171,1175,1220,1224,1230,1247,1251,1295,1300,1318,1322,1329,1335,1339,1345,1348,1353,1359,1364,1370,1373,1379,1405,1409,1412,1425,1457,1461,1465,1612,1618,1622,1663,1668,1672,1814,1818,1824,1833,1837,1840,2316,2376,2379,2389,2393,2397,2403,2420,2424,2427,2430,2433,2464,2467,2486,2489,2492,2578,2582,2588,2594,2605,2608,2634,2637,2640,2660,2663,2706,2709,2768,2771,2795],[10,11,5],"h1",{"id":12},"google-search-console-404エラー調査",[14,15,16],"h2",{"id":16},"問題の概要",[18,19,20],"p",{},"Google Search Consoleで以下の2つの問題が報告された：",[22,23,24,32],"ol",{},[25,26,27,31],"li",{},[28,29,30],"strong",{},"404エラー",": 15件のURLが「見つかりませんでした（404）」",[25,33,34,37],{},[28,35,36],{},"インデックス登録数が少ない",": サイトマップには177件あるのに29件しか登録されていない",[14,39,41],{"id":40},"問題1-coding-standards-の404エラー","問題1: coding-standards の404エラー",[43,44,45],"h3",{"id":45},"症状",[18,47,48],{},"以下のパターンのURLが404を返している：",[50,51,56],"pre",{"className":52,"code":54,"language":55},[53],"language-text","https://log.eurekapu.com/coding-standards/viewer/rule-8-5\nhttps://log.eurekapu.com/coding-standards/viewer/rule-10-7\nhttps://log.eurekapu.com/coding-standards/viewer/rule-10-6\n... 他多数\n","text",[57,58,54],"code",{"__ignoreMap":59},"",[43,61,62],{"id":62},"原因",[18,64,65,66,69,70,73],{},"動的ルート",[57,67,68],{},"/coding-standards/viewer/[ruleId].vue","で、",[28,71,72],{},"静的HTMLが生成されていない","。",[75,76,77],"h4",{"id":77},"ビルド出力の確認",[50,79,82],{"className":80,"code":81,"language":55},[53],"dist/coding-standards/viewer/\n├── index.html      ← これしかない\n└── _payload.json\n\n※ rule-8-5.html などは存在しない\n",[57,83,81],{"__ignoreMap":59},[75,85,86],{"id":86},"コードの問題点",[50,88,92],{"className":89,"code":90,"language":91,"meta":59,"style":59},"language-vue shiki shiki-themes vitesse-light vitesse-light","\u003C!-- apps/web/app/pages/coding-standards/viewer/[ruleId].vue -->\n\u003Ctemplate>\n  \u003CClientOnly>  \u003C!-- ← クライアントサイドのみでレンダリング -->\n    ...\n  \u003C/ClientOnly>\n\u003C/template>\n","vue",[57,93,94,103,117,132,139,149],{"__ignoreMap":59},[95,96,99],"span",{"class":97,"line":98},"line",1,[95,100,102],{"class":101},"sxvE3","\u003C!-- apps/web/app/pages/coding-standards/viewer/[ruleId].vue -->\n",[95,104,106,110,114],{"class":97,"line":105},2,[95,107,109],{"class":108},"shFtX","\u003C",[95,111,113],{"class":112},"sHkkW","template",[95,115,116],{"class":108},">\n",[95,118,120,123,126,129],{"class":97,"line":119},3,[95,121,122],{"class":108},"  \u003C",[95,124,125],{"class":112},"ClientOnly",[95,127,128],{"class":108},">",[95,130,131],{"class":101},"  \u003C!-- ← クライアントサイドのみでレンダリング -->\n",[95,133,135],{"class":97,"line":134},4,[95,136,138],{"class":137},"sG7-3","    ...\n",[95,140,142,145,147],{"class":97,"line":141},5,[95,143,144],{"class":108},"  \u003C/",[95,146,125],{"class":112},[95,148,116],{"class":108},[95,150,152,155,157],{"class":97,"line":151},6,[95,153,154],{"class":108},"\u003C/",[95,156,113],{"class":112},[95,158,116],{"class":108},[160,161,162,168,171],"ul",{},[25,163,164,167],{},[57,165,166],{},"\u003CClientOnly>","でラップされているため、SSG時に空のHTMLが生成される",[25,169,170],{},"クライアントサイドのみの動的ルートを、Googleボットは404として認識",[25,172,173],{},"内部リンク（前へ/次へボタン）からこれらのURLが発見され、クロール対象になっている",[43,175,176],{"id":176},"影響範囲",[18,178,179,182],{},[57,180,181],{},"coding-standards.json"," には約100以上のルールが定義されており、それぞれの個別URLが404になっている。",[14,184,186],{"id":185},"問題2-トレイリングスラッシュの重複404","問題2: トレイリングスラッシュの重複404",[43,188,45],{"id":189},"症状-1",[18,191,192],{},"同じページがスラッシュあり/なしの両方で404になっている：",[50,194,197],{"className":195,"code":196,"language":55},[53],"https://log.eurekapu.com/2025-12-09/nuxt-vite-optimize-deps-warning\nhttps://log.eurekapu.com/2025-12-09/nuxt-vite-optimize-deps-warning/\n\nhttps://log.eurekapu.com/2025-12-06/nuxt-prefetch-guide\nhttps://log.eurekapu.com/2025-12-06/nuxt-prefetch-guide/\n",[57,198,196],{"__ignoreMap":59},[43,200,201],{"id":201},"原因の可能性",[22,203,204,210,216],{},[25,205,206,209],{},[28,207,208],{},"コンテンツが削除された",": 該当のマークダウンファイルが存在しない",[25,211,212,215],{},[28,213,214],{},"パスの変更",": ファイル名やディレクトリ構造が変更された",[25,217,218,221],{},[28,219,220],{},"トレイリングスラッシュの設定",": Nuxtのルーティング設定の問題",[14,223,225],{"id":224},"問題3-cdn-cgi-の404","問題3: cdn-cgi の404",[43,227,45],{"id":228},"症状-2",[50,230,233],{"className":231,"code":232,"language":55},[53],"https://log.eurekapu.com/cdn-cgi/l/email-protection\n",[57,234,232],{"__ignoreMap":59},[43,236,62],{"id":237},"原因-1",[18,239,240,241,73],{},"これはCloudflareのメール保護機能に関連するURL。外部サイトからのリンクで発生した可能性が高い。",[28,242,243],{},"対応不要",[14,245,247],{"id":246},"実施した解決策-プリレンダリングssg対応","実施した解決策: プリレンダリング（SSG対応）",[43,249,251],{"id":250},"選択肢aを採用","選択肢Aを採用",[18,253,254],{},"全158ルールの静的HTMLを生成するよう動的ルートをSSG（Static Site Generation）対応にする。",[43,256,257],{"id":257},"実装内容",[75,259,261],{"id":260},"_1-nuxtconfigts-の修正","1. nuxt.config.ts の修正",[50,263,267],{"className":264,"code":265,"language":266,"meta":59,"style":59},"language-typescript shiki shiki-themes vitesse-light vitesse-light","// nuxt.config.ts\nimport { readFile } from \"node:fs/promises\";\n\n// JSONからルートを動的生成\nasync function getCodingStandardsRoutes(): Promise\u003Cstring[]> {\n  const jsonPath = resolve(__dirname, 'public/data/coding-standards.json');\n  const data = JSON.parse(await readFile(jsonPath, 'utf-8'));\n  return data.map((rule: { ruleNumber: string }) =>\n    `/coding-standards/viewer/rule-${rule.ruleNumber.replace('.', '-')}`\n  );\n}\n\nexport default defineNuxtConfig({\n  hooks: {\n    'nitro:config': async (nitroConfig) => {\n      const routes = await getCodingStandardsRoutes();\n      nitroConfig.prerender.routes = [\n        ...(nitroConfig.prerender.routes || []),\n        ...routes\n      ];\n      console.log(`✓ Added ${routes.length} coding-standards routes for prerendering`);\n    }\n  }\n})\n","typescript",[57,268,269,274,306,312,317,348,383,425,462,511,517,523,528,543,553,577,596,614,636,645,651,688,694,700],{"__ignoreMap":59},[95,270,271],{"class":97,"line":98},[95,272,273],{"class":101},"// nuxt.config.ts\n",[95,275,276,279,282,286,289,292,296,300,303],{"class":97,"line":105},[95,277,278],{"class":112},"import",[95,280,281],{"class":108}," {",[95,283,285],{"class":284},"s4oTP"," readFile",[95,287,288],{"class":108}," }",[95,290,291],{"class":112}," from",[95,293,295],{"class":294},"sMJiu"," \"",[95,297,299],{"class":298},"sdGka","node:fs/promises",[95,301,302],{"class":294},"\"",[95,304,305],{"class":108},";\n",[95,307,308],{"class":97,"line":119},[95,309,311],{"emptyLinePlaceholder":310},true,"\n",[95,313,314],{"class":97,"line":134},[95,315,316],{"class":101},"// JSONからルートを動的生成\n",[95,318,319,323,326,330,333,337,339,342,345],{"class":97,"line":141},[95,320,322],{"class":321},"stQ0i","async",[95,324,325],{"class":321}," function",[95,327,329],{"class":328},"senZ8"," getCodingStandardsRoutes",[95,331,332],{"class":108},"():",[95,334,336],{"class":335},"sSkh3"," Promise",[95,338,109],{"class":108},[95,340,341],{"class":335},"string",[95,343,344],{"class":108},"[]>",[95,346,347],{"class":108}," {\n",[95,349,350,353,356,359,362,365,368,371,374,377,380],{"class":97,"line":151},[95,351,352],{"class":321},"  const ",[95,354,355],{"class":284},"jsonPath",[95,357,358],{"class":108}," =",[95,360,361],{"class":328}," resolve",[95,363,364],{"class":108},"(",[95,366,367],{"class":284},"__dirname",[95,369,370],{"class":108},",",[95,372,373],{"class":294}," '",[95,375,376],{"class":298},"public/data/coding-standards.json",[95,378,379],{"class":294},"'",[95,381,382],{"class":108},");\n",[95,384,386,388,391,393,396,399,402,404,407,409,411,413,415,417,420,422],{"class":97,"line":385},7,[95,387,352],{"class":321},[95,389,390],{"class":284},"data",[95,392,358],{"class":108},[95,394,395],{"class":284}," JSON",[95,397,398],{"class":108},".",[95,400,401],{"class":328},"parse",[95,403,364],{"class":108},[95,405,406],{"class":112},"await",[95,408,285],{"class":328},[95,410,364],{"class":108},[95,412,355],{"class":284},[95,414,370],{"class":108},[95,416,373],{"class":294},[95,418,419],{"class":298},"utf-8",[95,421,379],{"class":294},[95,423,424],{"class":108},"));\n",[95,426,428,431,434,436,439,442,445,448,451,454,456,459],{"class":97,"line":427},8,[95,429,430],{"class":112},"  return",[95,432,433],{"class":284}," data",[95,435,398],{"class":108},[95,437,438],{"class":328},"map",[95,440,441],{"class":108},"((",[95,443,444],{"class":284},"rule",[95,446,447],{"class":108},": { ",[95,449,450],{"class":284},"ruleNumber",[95,452,453],{"class":108},": ",[95,455,341],{"class":335},[95,457,458],{"class":108}," })",[95,460,461],{"class":108}," =>\n",[95,463,465,468,471,474,476,478,480,482,485,487,489,491,493,495,497,500,502,505,508],{"class":97,"line":464},9,[95,466,467],{"class":294},"    `",[95,469,470],{"class":298},"/coding-standards/viewer/rule-",[95,472,473],{"class":112},"${",[95,475,444],{"class":298},[95,477,398],{"class":108},[95,479,450],{"class":298},[95,481,398],{"class":108},[95,483,484],{"class":328},"replace",[95,486,364],{"class":108},[95,488,379],{"class":294},[95,490,398],{"class":298},[95,492,379],{"class":294},[95,494,370],{"class":108},[95,496,373],{"class":294},[95,498,499],{"class":298},"-",[95,501,379],{"class":294},[95,503,504],{"class":108},")",[95,506,507],{"class":112},"}",[95,509,510],{"class":294},"`\n",[95,512,514],{"class":97,"line":513},10,[95,515,516],{"class":108},"  );\n",[95,518,520],{"class":97,"line":519},11,[95,521,522],{"class":108},"}\n",[95,524,526],{"class":97,"line":525},12,[95,527,311],{"emptyLinePlaceholder":310},[95,529,531,534,537,540],{"class":97,"line":530},13,[95,532,533],{"class":112},"export",[95,535,536],{"class":112}," default",[95,538,539],{"class":328}," defineNuxtConfig",[95,541,542],{"class":108},"({\n",[95,544,546,550],{"class":97,"line":545},14,[95,547,549],{"class":548},"sz8Xr","  hooks",[95,551,552],{"class":108},": {\n",[95,554,556,559,562,564,566,568,571,574],{"class":97,"line":555},15,[95,557,558],{"class":294},"    '",[95,560,561],{"class":298},"nitro:config",[95,563,379],{"class":294},[95,565,453],{"class":108},[95,567,322],{"class":321},[95,569,570],{"class":108}," (",[95,572,573],{"class":284},"nitroConfig",[95,575,576],{"class":108},") => {\n",[95,578,580,583,586,588,591,593],{"class":97,"line":579},16,[95,581,582],{"class":321},"      const ",[95,584,585],{"class":284},"routes",[95,587,358],{"class":108},[95,589,590],{"class":112}," await",[95,592,329],{"class":328},[95,594,595],{"class":108},"();\n",[95,597,599,602,604,607,609,611],{"class":97,"line":598},17,[95,600,601],{"class":284},"      nitroConfig",[95,603,398],{"class":108},[95,605,606],{"class":284},"prerender",[95,608,398],{"class":108},[95,610,585],{"class":284},[95,612,613],{"class":108}," = [\n",[95,615,617,620,622,624,626,628,630,633],{"class":97,"line":616},18,[95,618,619],{"class":108},"        ...(",[95,621,573],{"class":284},[95,623,398],{"class":108},[95,625,606],{"class":284},[95,627,398],{"class":108},[95,629,585],{"class":284},[95,631,632],{"class":321}," ||",[95,634,635],{"class":108}," []),\n",[95,637,639,642],{"class":97,"line":638},19,[95,640,641],{"class":108},"        ...",[95,643,644],{"class":284},"routes\n",[95,646,648],{"class":97,"line":647},20,[95,649,650],{"class":108},"      ];\n",[95,652,654,657,659,662,664,667,670,672,674,676,679,681,684,686],{"class":97,"line":653},21,[95,655,656],{"class":284},"      console",[95,658,398],{"class":108},[95,660,661],{"class":328},"log",[95,663,364],{"class":108},[95,665,666],{"class":294},"`",[95,668,669],{"class":298},"✓ Added ",[95,671,473],{"class":112},[95,673,585],{"class":298},[95,675,398],{"class":108},[95,677,678],{"class":548},"length",[95,680,507],{"class":112},[95,682,683],{"class":298}," coding-standards routes for prerendering",[95,685,666],{"class":294},[95,687,382],{"class":108},[95,689,691],{"class":97,"line":690},22,[95,692,693],{"class":108},"    }\n",[95,695,697],{"class":97,"line":696},23,[95,698,699],{"class":108},"  }\n",[95,701,703],{"class":97,"line":702},24,[95,704,705],{"class":108},"})\n",[75,707,709,710,713],{"id":708},"_2-ruleidvue-のssr対応","2. ",[95,711,712],{},"ruleId",".vue のSSR対応",[18,715,716],{},[28,717,718],{},"修正前（問題のあるコード）:",[50,720,722],{"className":89,"code":721,"language":91,"meta":59,"style":59},"\u003Ctemplate>\n  \u003CClientOnly>  \u003C!-- ← SSG時に空のHTMLになる -->\n    \u003Cdiv v-if=\"currentRule\">...\u003C/div>\n  \u003C/ClientOnly>\n\u003C/template>\n\n\u003Cscript setup>\n// クライアントサイドでfetch → SSGでは動作しない\nconst response = await fetch('/data/coding-standards.json');\n\u003C/script>\n",[57,723,724,732,743,775,783,791,795,807,812,838],{"__ignoreMap":59},[95,725,726,728,730],{"class":97,"line":98},[95,727,109],{"class":108},[95,729,113],{"class":112},[95,731,116],{"class":108},[95,733,734,736,738,740],{"class":97,"line":105},[95,735,122],{"class":108},[95,737,125],{"class":112},[95,739,128],{"class":108},[95,741,742],{"class":101},"  \u003C!-- ← SSG時に空のHTMLになる -->\n",[95,744,745,748,751,754,757,759,762,764,766,769,771,773],{"class":97,"line":119},[95,746,747],{"class":108},"    \u003C",[95,749,750],{"class":112},"div",[95,752,753],{"class":284}," v-if",[95,755,756],{"class":108},"=",[95,758,302],{"class":294},[95,760,761],{"class":298},"currentRule",[95,763,302],{"class":294},[95,765,128],{"class":108},[95,767,768],{"class":137},"...",[95,770,154],{"class":108},[95,772,750],{"class":112},[95,774,116],{"class":108},[95,776,777,779,781],{"class":97,"line":134},[95,778,144],{"class":108},[95,780,125],{"class":112},[95,782,116],{"class":108},[95,784,785,787,789],{"class":97,"line":141},[95,786,154],{"class":108},[95,788,113],{"class":112},[95,790,116],{"class":108},[95,792,793],{"class":97,"line":151},[95,794,311],{"emptyLinePlaceholder":310},[95,796,797,799,802,805],{"class":97,"line":385},[95,798,109],{"class":108},[95,800,801],{"class":112},"script",[95,803,804],{"class":284}," setup",[95,806,116],{"class":108},[95,808,809],{"class":97,"line":427},[95,810,811],{"class":101},"// クライアントサイドでfetch → SSGでは動作しない\n",[95,813,814,817,820,822,824,827,829,831,834,836],{"class":97,"line":464},[95,815,816],{"class":321},"const",[95,818,819],{"class":284}," response",[95,821,358],{"class":108},[95,823,590],{"class":112},[95,825,826],{"class":328}," fetch",[95,828,364],{"class":108},[95,830,379],{"class":294},[95,832,833],{"class":298},"/data/coding-standards.json",[95,835,379],{"class":294},[95,837,382],{"class":108},[95,839,840,842,844],{"class":97,"line":513},[95,841,154],{"class":108},[95,843,801],{"class":112},[95,845,116],{"class":108},[18,847,848],{},[28,849,850],{},"修正後（SSG対応）:",[50,852,854],{"className":89,"code":853,"language":91,"meta":59,"style":59},"\u003Ctemplate>\n  \u003C!-- ClientOnlyを削除 → SSGで完全なHTMLが生成される -->\n  \u003Cdiv v-if=\"currentRule\">...\u003C/div>\n\u003C/template>\n\n\u003Cscript setup>\n// 直接import → SSG時にデータが埋め込まれる\nimport codingStandardsData from '../../../../public/data/coding-standards.json';\nconst allRules = ref(codingStandardsData);\n\n// highlight.jsはクライアントサイドのみで実行\nasync function highlightCode() {\n  if (import.meta.server) return;  // SSR時はスキップ\n  const hljs = (await import('highlight.js/lib/core')).default;\n  // ...\n}\n\u003C/script>\n",[57,855,856,864,869,895,903,907,917,922,940,959,963,968,982,1012,1046,1051,1055],{"__ignoreMap":59},[95,857,858,860,862],{"class":97,"line":98},[95,859,109],{"class":108},[95,861,113],{"class":112},[95,863,116],{"class":108},[95,865,866],{"class":97,"line":105},[95,867,868],{"class":101},"  \u003C!-- ClientOnlyを削除 → SSGで完全なHTMLが生成される -->\n",[95,870,871,873,875,877,879,881,883,885,887,889,891,893],{"class":97,"line":119},[95,872,122],{"class":108},[95,874,750],{"class":112},[95,876,753],{"class":284},[95,878,756],{"class":108},[95,880,302],{"class":294},[95,882,761],{"class":298},[95,884,302],{"class":294},[95,886,128],{"class":108},[95,888,768],{"class":137},[95,890,154],{"class":108},[95,892,750],{"class":112},[95,894,116],{"class":108},[95,896,897,899,901],{"class":97,"line":134},[95,898,154],{"class":108},[95,900,113],{"class":112},[95,902,116],{"class":108},[95,904,905],{"class":97,"line":141},[95,906,311],{"emptyLinePlaceholder":310},[95,908,909,911,913,915],{"class":97,"line":151},[95,910,109],{"class":108},[95,912,801],{"class":112},[95,914,804],{"class":284},[95,916,116],{"class":108},[95,918,919],{"class":97,"line":385},[95,920,921],{"class":101},"// 直接import → SSG時にデータが埋め込まれる\n",[95,923,924,926,929,931,933,936,938],{"class":97,"line":427},[95,925,278],{"class":112},[95,927,928],{"class":284}," codingStandardsData",[95,930,291],{"class":112},[95,932,373],{"class":294},[95,934,935],{"class":298},"../../../../public/data/coding-standards.json",[95,937,379],{"class":294},[95,939,305],{"class":108},[95,941,942,944,947,949,952,954,957],{"class":97,"line":464},[95,943,816],{"class":321},[95,945,946],{"class":284}," allRules",[95,948,358],{"class":108},[95,950,951],{"class":328}," ref",[95,953,364],{"class":108},[95,955,956],{"class":284},"codingStandardsData",[95,958,382],{"class":108},[95,960,961],{"class":97,"line":513},[95,962,311],{"emptyLinePlaceholder":310},[95,964,965],{"class":97,"line":519},[95,966,967],{"class":101},"// highlight.jsはクライアントサイドのみで実行\n",[95,969,970,972,974,977,980],{"class":97,"line":525},[95,971,322],{"class":321},[95,973,325],{"class":321},[95,975,976],{"class":328}," highlightCode",[95,978,979],{"class":108},"()",[95,981,347],{"class":108},[95,983,984,987,989,991,993,996,998,1001,1003,1006,1009],{"class":97,"line":530},[95,985,986],{"class":112},"  if",[95,988,570],{"class":108},[95,990,278],{"class":112},[95,992,398],{"class":108},[95,994,995],{"class":548},"meta",[95,997,398],{"class":108},[95,999,1000],{"class":284},"server",[95,1002,504],{"class":108},[95,1004,1005],{"class":112}," return",[95,1007,1008],{"class":108},";",[95,1010,1011],{"class":101},"  // SSR時はスキップ\n",[95,1013,1014,1017,1020,1022,1024,1026,1029,1031,1033,1036,1038,1041,1044],{"class":97,"line":545},[95,1015,1016],{"class":321},"  const",[95,1018,1019],{"class":284}," hljs",[95,1021,358],{"class":108},[95,1023,570],{"class":108},[95,1025,406],{"class":112},[95,1027,1028],{"class":321}," import",[95,1030,364],{"class":108},[95,1032,379],{"class":294},[95,1034,1035],{"class":298},"highlight.js/lib/core",[95,1037,379],{"class":294},[95,1039,1040],{"class":108},")).",[95,1042,1043],{"class":284},"default",[95,1045,305],{"class":108},[95,1047,1048],{"class":97,"line":555},[95,1049,1050],{"class":101},"  // ...\n",[95,1052,1053],{"class":97,"line":579},[95,1054,522],{"class":108},[95,1056,1057,1059,1061],{"class":97,"line":598},[95,1058,154],{"class":108},[95,1060,801],{"class":112},[95,1062,116],{"class":108},[43,1064,1066],{"id":1065},"試行錯誤-ssr対応で失敗したパターン","試行錯誤: SSR対応で失敗したパターン",[75,1068,1070],{"id":1069},"失敗1-usefetch-を使用-500エラー","失敗1: useFetch を使用 → 500エラー",[50,1072,1074],{"className":89,"code":1073,"language":91,"meta":59,"style":59},"\u003Cscript setup>\n// ❌ SSG時に500エラーが発生\nconst { data: allRules } = await useFetch('/data/coding-standards.json', {\n  default: () => []\n});\n\u003C/script>\n",[57,1075,1076,1086,1091,1125,1141,1146],{"__ignoreMap":59},[95,1077,1078,1080,1082,1084],{"class":97,"line":98},[95,1079,109],{"class":108},[95,1081,801],{"class":112},[95,1083,804],{"class":284},[95,1085,116],{"class":108},[95,1087,1088],{"class":97,"line":105},[95,1089,1090],{"class":101},"// ❌ SSG時に500エラーが発生\n",[95,1092,1093,1095,1097,1099,1102,1104,1106,1108,1110,1113,1115,1117,1119,1121,1123],{"class":97,"line":119},[95,1094,816],{"class":321},[95,1096,281],{"class":108},[95,1098,433],{"class":284},[95,1100,1101],{"class":108},":",[95,1103,946],{"class":284},[95,1105,288],{"class":108},[95,1107,358],{"class":108},[95,1109,590],{"class":112},[95,1111,1112],{"class":328}," useFetch",[95,1114,364],{"class":108},[95,1116,379],{"class":294},[95,1118,833],{"class":298},[95,1120,379],{"class":294},[95,1122,370],{"class":108},[95,1124,347],{"class":108},[95,1126,1127,1130,1132,1135,1138],{"class":97,"line":134},[95,1128,1129],{"class":328},"  default",[95,1131,1101],{"class":108},[95,1133,1134],{"class":108}," ()",[95,1136,1137],{"class":108}," =>",[95,1139,1140],{"class":108}," []\n",[95,1142,1143],{"class":97,"line":141},[95,1144,1145],{"class":108},"});\n",[95,1147,1148,1150,1152],{"class":97,"line":151},[95,1149,154],{"class":108},[95,1151,801],{"class":112},[95,1153,116],{"class":108},[18,1155,1156],{},[28,1157,1158],{},"エラー内容:",[50,1160,1163],{"className":1161,"code":1162,"language":55},[53],"[nitro] ├─ /coding-standards/viewer/rule-8-5 (766ms)\n        │ └── [500] Server Error\n",[57,1164,1162],{"__ignoreMap":59},[18,1166,1167,1170],{},[28,1168,1169],{},"原因:"," SSG時にpublicディレクトリへのfetchが解決できない。",[75,1172,1174],{"id":1173},"失敗2-public-パスでimport-ビルドエラー","失敗2: ~/public パスでimport → ビルドエラー",[50,1176,1178],{"className":89,"code":1177,"language":91,"meta":59,"style":59},"\u003Cscript setup>\n// ❌ パスが解決できない\nimport codingStandardsData from '~/public/data/coding-standards.json';\n\u003C/script>\n",[57,1179,1180,1190,1195,1212],{"__ignoreMap":59},[95,1181,1182,1184,1186,1188],{"class":97,"line":98},[95,1183,109],{"class":108},[95,1185,801],{"class":112},[95,1187,804],{"class":284},[95,1189,116],{"class":108},[95,1191,1192],{"class":97,"line":105},[95,1193,1194],{"class":101},"// ❌ パスが解決できない\n",[95,1196,1197,1199,1201,1203,1205,1208,1210],{"class":97,"line":119},[95,1198,278],{"class":112},[95,1200,928],{"class":284},[95,1202,291],{"class":112},[95,1204,373],{"class":294},[95,1206,1207],{"class":298},"~/public/data/coding-standards.json",[95,1209,379],{"class":294},[95,1211,305],{"class":108},[95,1213,1214,1216,1218],{"class":97,"line":134},[95,1215,154],{"class":108},[95,1217,801],{"class":112},[95,1219,116],{"class":108},[18,1221,1222],{},[28,1223,1158],{},[50,1225,1228],{"className":1226,"code":1227,"language":55},[53],"ERROR [vite:load-fallback] Could not load C:/Users/.../app//public/data/coding-standards.json\nENOENT: no such file or directory\n",[57,1229,1227],{"__ignoreMap":59},[18,1231,1232,1234,1235,1238,1239,1242,1243,1246],{},[28,1233,1169],{}," ",[57,1236,1237],{},"~"," エイリアスは ",[57,1240,1241],{},"app/"," ディレクトリを指すため、",[57,1244,1245],{},"public/"," に到達できない。",[75,1248,1250],{"id":1249},"成功-相対パスでimport","成功: 相対パスでimport",[50,1252,1254],{"className":89,"code":1253,"language":91,"meta":59,"style":59},"\u003Cscript setup>\n// ✅ 相対パスで正しく解決される\nimport codingStandardsData from '../../../../public/data/coding-standards.json';\n\u003C/script>\n",[57,1255,1256,1266,1271,1287],{"__ignoreMap":59},[95,1257,1258,1260,1262,1264],{"class":97,"line":98},[95,1259,109],{"class":108},[95,1261,801],{"class":112},[95,1263,804],{"class":284},[95,1265,116],{"class":108},[95,1267,1268],{"class":97,"line":105},[95,1269,1270],{"class":101},"// ✅ 相対パスで正しく解決される\n",[95,1272,1273,1275,1277,1279,1281,1283,1285],{"class":97,"line":119},[95,1274,278],{"class":112},[95,1276,928],{"class":284},[95,1278,291],{"class":112},[95,1280,373],{"class":294},[95,1282,935],{"class":298},[95,1284,379],{"class":294},[95,1286,305],{"class":108},[95,1288,1289,1291,1293],{"class":97,"line":134},[95,1290,154],{"class":108},[95,1292,801],{"class":112},[95,1294,116],{"class":108},[18,1296,1297],{},[28,1298,1299],{},"ポイント:",[160,1301,1302,1312],{},[25,1303,1304,1307,1308,1311],{},[57,1305,1306],{},"app/pages/coding-standards/viewer/[ruleId].vue"," から ",[57,1309,1310],{},"public/data/"," への相対パス",[25,1313,1314,1315,1317],{},"4階層上がって ",[57,1316,1310],{}," に到達",[43,1319,1321],{"id":1320},"ssrssgの仕組み解説","SSR/SSGの仕組み解説",[75,1323,1325,1326,1328],{"id":1324},"なぜ-clientonly-だと404になるのか","なぜ ",[57,1327,166],{}," だと404になるのか",[50,1330,1333],{"className":1331,"code":1332,"language":55},[53],"┌─────────────────────────────────────────────────────────┐\n│  ビルド時（SSG）                                          │\n├─────────────────────────────────────────────────────────┤\n│  1. Nuxtが /coding-standards/viewer/rule-8-5 をレンダリング │\n│  2. \u003CClientOnly> の中身はスキップされる                    │\n│  3. 空のHTMLが生成される                                  │\n│                                                         │\n│  結果: Googleボットが見るのは空のページ → 404扱い           │\n└─────────────────────────────────────────────────────────┘\n",[57,1334,1332],{"__ignoreMap":59},[75,1336,1338],{"id":1337},"ssg対応後の流れ","SSG対応後の流れ",[50,1340,1343],{"className":1341,"code":1342,"language":55},[53],"┌─────────────────────────────────────────────────────────┐\n│  ビルド時（SSG）                                          │\n├─────────────────────────────────────────────────────────┤\n│  1. JSONを直接import → データがビルドに含まれる            │\n│  2. \u003CClientOnly>なし → 完全なHTMLが生成される              │\n│  3. 各ルールページの静的HTMLがdist/に出力                  │\n│                                                         │\n│  結果: Googleボットが見るのは完全なコンテンツ               │\n└─────────────────────────────────────────────────────────┘\n",[57,1344,1342],{"__ignoreMap":59},[75,1346,1347],{"id":1347},"ビルド出力の比較",[18,1349,1350],{},[28,1351,1352],{},"修正前:",[50,1354,1357],{"className":1355,"code":1356,"language":55},[53],"dist/coding-standards/viewer/\n├── index.html\n└── _payload.json\n",[57,1358,1356],{"__ignoreMap":59},[18,1360,1361],{},[28,1362,1363],{},"修正後:",[50,1365,1368],{"className":1366,"code":1367,"language":55},[53],"dist/coding-standards/viewer/\n├── index.html\n├── rule-1-1/index.html    ← 新規生成\n├── rule-1-2/index.html    ← 新規生成\n├── rule-8-5/index.html    ← 新規生成\n├── ...（全158ルール）\n└── _payload.json\n",[57,1369,1367],{"__ignoreMap":59},[43,1371,1372],{"id":1372},"ビルド結果",[50,1374,1377],{"className":1375,"code":1376,"language":55},[53],"✓ Added 158 coding-standards routes for prerendering\nPrerendered 579 routes in 35.078 seconds\n✓ Generated sitemap.xml with 287 URLs\n  - Coding standards rules: 158\n  - Other pages: 129\n",[57,1378,1376],{"__ignoreMap":59},[160,1380,1381,1387,1393,1399],{},[25,1382,1383,1386],{},[28,1384,1385],{},"追加ルート数",": 158件（coding-standards）",[25,1388,1389,1392],{},[28,1390,1391],{},"総プリレンダリング数",": 579ルート",[25,1394,1395,1398],{},[28,1396,1397],{},"サイトマップURL数",": 287件",[25,1400,1401,1404],{},[28,1402,1403],{},"ビルド時間",": 約35秒",[14,1406,1408],{"id":1407},"落とし穴-nuxtjssitemap-と-cloudflare-pages-static","落とし穴: @nuxtjs/sitemap と cloudflare-pages-static",[43,1410,1411],{"id":1411},"問題",[18,1413,1414,1417,1418,1421,1422,73],{},[57,1415,1416],{},"@nuxtjs/sitemap"," v7は ",[57,1419,1420],{},"cloudflare-pages-static"," プリセットと組み合わせると、",[28,1423,1424],{},"空のサイトマップが生成される",[50,1426,1430],{"className":1427,"code":1428,"language":1429,"meta":59,"style":59},"language-xml shiki shiki-themes vitesse-light vitesse-light","\u003C!-- 生成されるsitemap.xml（空） -->\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003Curlset xmlns=\"...\">\n\u003C/urlset>\n\u003C!-- XML Sitemap generated by @nuxtjs/sitemap v7.4.8 -->\n","xml",[57,1431,1432,1437,1442,1447,1452],{"__ignoreMap":59},[95,1433,1434],{"class":97,"line":98},[95,1435,1436],{},"\u003C!-- 生成されるsitemap.xml（空） -->\n",[95,1438,1439],{"class":97,"line":105},[95,1440,1441],{},"\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",[95,1443,1444],{"class":97,"line":119},[95,1445,1446],{},"\u003Curlset xmlns=\"...\">\n",[95,1448,1449],{"class":97,"line":134},[95,1450,1451],{},"\u003C/urlset>\n",[95,1453,1454],{"class":97,"line":141},[95,1455,1456],{},"\u003C!-- XML Sitemap generated by @nuxtjs/sitemap v7.4.8 -->\n",[43,1458,1460],{"id":1459},"試した方法すべて失敗","試した方法（すべて失敗）",[75,1462,1464],{"id":1463},"失敗1-sitemapurls-オプション","失敗1: sitemap.urls オプション",[50,1466,1468],{"className":264,"code":1467,"language":266,"meta":59,"style":59},"// nuxt.config.ts\nsitemap: {\n  urls: async () => {\n    const data = JSON.parse(await readFile(jsonPath, 'utf-8'));\n    return data.map(rule => ({\n      loc: `/coding-standards/viewer/rule-${rule.ruleNumber.replace('.', '-')}`\n    }));\n  }\n}\n",[57,1469,1470,1474,1483,1499,1534,1554,1599,1604,1608],{"__ignoreMap":59},[95,1471,1472],{"class":97,"line":98},[95,1473,273],{"class":101},[95,1475,1476,1479,1481],{"class":97,"line":105},[95,1477,1478],{"class":328},"sitemap",[95,1480,1101],{"class":108},[95,1482,347],{"class":108},[95,1484,1485,1488,1490,1493,1495,1497],{"class":97,"line":119},[95,1486,1487],{"class":328},"  urls",[95,1489,1101],{"class":108},[95,1491,1492],{"class":321}," async",[95,1494,1134],{"class":108},[95,1496,1137],{"class":108},[95,1498,347],{"class":108},[95,1500,1501,1504,1506,1508,1510,1512,1514,1516,1518,1520,1522,1524,1526,1528,1530,1532],{"class":97,"line":134},[95,1502,1503],{"class":321},"    const ",[95,1505,390],{"class":284},[95,1507,358],{"class":108},[95,1509,395],{"class":284},[95,1511,398],{"class":108},[95,1513,401],{"class":328},[95,1515,364],{"class":108},[95,1517,406],{"class":112},[95,1519,285],{"class":328},[95,1521,364],{"class":108},[95,1523,355],{"class":284},[95,1525,370],{"class":108},[95,1527,373],{"class":294},[95,1529,419],{"class":298},[95,1531,379],{"class":294},[95,1533,424],{"class":108},[95,1535,1536,1539,1541,1543,1545,1547,1549,1551],{"class":97,"line":141},[95,1537,1538],{"class":112},"    return",[95,1540,433],{"class":284},[95,1542,398],{"class":108},[95,1544,438],{"class":328},[95,1546,364],{"class":108},[95,1548,444],{"class":284},[95,1550,1137],{"class":108},[95,1552,1553],{"class":108}," ({\n",[95,1555,1556,1559,1561,1563,1565,1567,1569,1571,1573,1575,1577,1579,1581,1583,1585,1587,1589,1591,1593,1595,1597],{"class":97,"line":151},[95,1557,1558],{"class":548},"      loc",[95,1560,453],{"class":108},[95,1562,666],{"class":294},[95,1564,470],{"class":298},[95,1566,473],{"class":112},[95,1568,444],{"class":298},[95,1570,398],{"class":108},[95,1572,450],{"class":298},[95,1574,398],{"class":108},[95,1576,484],{"class":328},[95,1578,364],{"class":108},[95,1580,379],{"class":294},[95,1582,398],{"class":298},[95,1584,379],{"class":294},[95,1586,370],{"class":108},[95,1588,373],{"class":294},[95,1590,499],{"class":298},[95,1592,379],{"class":294},[95,1594,504],{"class":108},[95,1596,507],{"class":112},[95,1598,510],{"class":294},[95,1600,1601],{"class":97,"line":385},[95,1602,1603],{"class":108},"    }));\n",[95,1605,1606],{"class":97,"line":427},[95,1607,699],{"class":108},[95,1609,1610],{"class":97,"line":464},[95,1611,522],{"class":108},[18,1613,1614,1617],{},[28,1615,1616],{},"結果:"," サイトマップが完全に空になる（他のページも含まれない）",[75,1619,1621],{"id":1620},"失敗2-sitemapsources-オプション","失敗2: sitemap.sources オプション",[50,1623,1625],{"className":264,"code":1624,"language":266,"meta":59,"style":59},"// nuxt.config.ts\nsitemap: {\n  sources: ['/api/__sitemap__/coding-standards']\n}\n",[57,1626,1627,1631,1639,1659],{"__ignoreMap":59},[95,1628,1629],{"class":97,"line":98},[95,1630,273],{"class":101},[95,1632,1633,1635,1637],{"class":97,"line":105},[95,1634,1478],{"class":328},[95,1636,1101],{"class":108},[95,1638,347],{"class":108},[95,1640,1641,1644,1646,1649,1651,1654,1656],{"class":97,"line":119},[95,1642,1643],{"class":328},"  sources",[95,1645,1101],{"class":108},[95,1647,1648],{"class":108}," [",[95,1650,379],{"class":294},[95,1652,1653],{"class":298},"/api/__sitemap__/coding-standards",[95,1655,379],{"class":294},[95,1657,1658],{"class":108},"]\n",[95,1660,1661],{"class":97,"line":134},[95,1662,522],{"class":108},[18,1664,1665,1667],{},[28,1666,1616],{}," APIエンドポイントが呼ばれない、サイトマップは空のまま",[75,1669,1671],{"id":1670},"失敗3-サーバーapiエンドポイント","失敗3: サーバーAPIエンドポイント",[50,1673,1675],{"className":264,"code":1674,"language":266,"meta":59,"style":59},"// server/api/__sitemap__/coding-standards.ts\nimport { defineSitemapEventHandler } from '#imports'\nimport { readFileSync } from 'fs'\n\nexport default defineSitemapEventHandler(() => {\n  const data = JSON.parse(readFileSync(jsonPath, 'utf-8'))\n  return data.map(rule => ({ loc: `/coding-standards/viewer/rule-...` }))\n})\n",[57,1676,1677,1682,1703,1723,1727,1742,1776,1810],{"__ignoreMap":59},[95,1678,1679],{"class":97,"line":98},[95,1680,1681],{"class":101},"// server/api/__sitemap__/coding-standards.ts\n",[95,1683,1684,1686,1688,1691,1693,1695,1697,1700],{"class":97,"line":105},[95,1685,278],{"class":112},[95,1687,281],{"class":108},[95,1689,1690],{"class":284}," defineSitemapEventHandler",[95,1692,288],{"class":108},[95,1694,291],{"class":112},[95,1696,373],{"class":294},[95,1698,1699],{"class":298},"#imports",[95,1701,1702],{"class":294},"'\n",[95,1704,1705,1707,1709,1712,1714,1716,1718,1721],{"class":97,"line":119},[95,1706,278],{"class":112},[95,1708,281],{"class":108},[95,1710,1711],{"class":284}," readFileSync",[95,1713,288],{"class":108},[95,1715,291],{"class":112},[95,1717,373],{"class":294},[95,1719,1720],{"class":298},"fs",[95,1722,1702],{"class":294},[95,1724,1725],{"class":97,"line":134},[95,1726,311],{"emptyLinePlaceholder":310},[95,1728,1729,1731,1733,1735,1738,1740],{"class":97,"line":141},[95,1730,533],{"class":112},[95,1732,536],{"class":112},[95,1734,1690],{"class":328},[95,1736,1737],{"class":108},"(()",[95,1739,1137],{"class":108},[95,1741,347],{"class":108},[95,1743,1744,1746,1748,1750,1752,1754,1756,1758,1761,1763,1765,1767,1769,1771,1773],{"class":97,"line":151},[95,1745,352],{"class":321},[95,1747,390],{"class":284},[95,1749,358],{"class":108},[95,1751,395],{"class":284},[95,1753,398],{"class":108},[95,1755,401],{"class":328},[95,1757,364],{"class":108},[95,1759,1760],{"class":328},"readFileSync",[95,1762,364],{"class":108},[95,1764,355],{"class":284},[95,1766,370],{"class":108},[95,1768,373],{"class":294},[95,1770,419],{"class":298},[95,1772,379],{"class":294},[95,1774,1775],{"class":108},"))\n",[95,1777,1778,1780,1782,1784,1786,1788,1790,1792,1795,1798,1800,1802,1805,1807],{"class":97,"line":385},[95,1779,430],{"class":112},[95,1781,433],{"class":284},[95,1783,398],{"class":108},[95,1785,438],{"class":328},[95,1787,364],{"class":108},[95,1789,444],{"class":284},[95,1791,1137],{"class":108},[95,1793,1794],{"class":108}," ({ ",[95,1796,1797],{"class":548},"loc",[95,1799,453],{"class":108},[95,1801,666],{"class":294},[95,1803,1804],{"class":298},"/coding-standards/viewer/rule-...",[95,1806,666],{"class":294},[95,1808,1809],{"class":108}," }))\n",[95,1811,1812],{"class":97,"line":427},[95,1813,705],{"class":108},[18,1815,1816],{},[28,1817,1158],{},[50,1819,1822],{"className":1820,"code":1821,"language":55},[53],"RollupError: Could not resolve \"../../../../public/data/coding-standards.json\"\n",[57,1823,1821],{"__ignoreMap":59},[18,1825,1826,1828,1829,1832],{},[28,1827,1169],{}," サーバーサイドのコードからの相対パスimportはRollupで解決できない。\n",[57,1830,1831],{},"process.cwd()"," を使ったパスも、SSG時には正しく動作しない。",[43,1834,1836],{"id":1835},"解決策-カスタムスクリプト","解決策: カスタムスクリプト",[18,1838,1839],{},"ビルド後にカスタムスクリプトでサイトマップを生成する。",[50,1841,1845],{"className":1842,"code":1843,"language":1844,"meta":59,"style":59},"language-javascript shiki shiki-themes vitesse-light vitesse-light","// scripts/generate-sitemap.mjs\nimport { readdirSync, writeFileSync } from 'fs'\nimport { join, resolve } from 'path'\n\nconst SITE_URL = 'https://log.eurekapu.com'\nconst DIST_DIR = resolve(process.cwd(), 'dist')\n\n// distディレクトリから全HTMLファイルを検出\nfunction getAllRoutes(dir, baseRoute = '') {\n  const routes = []\n  const entries = readdirSync(dir, { withFileTypes: true })\n\n  for (const entry of entries) {\n    if (entry.isDirectory() && !entry.name.startsWith('_')) {\n      routes.push(...getAllRoutes(join(dir, entry.name), `${baseRoute}/${entry.name}`))\n    } else if (entry.name === 'index.html') {\n      routes.push(baseRoute || '/')\n    }\n  }\n  return routes\n}\n\n// サイトマップXMLを生成\nconst routes = getAllRoutes(DIST_DIR)\nconst sitemap = generateSitemap(routes)\nwriteFileSync(join(DIST_DIR, 'sitemap.xml'), sitemap)\n","javascript",[57,1846,1847,1852,1876,1900,1904,1920,1954,1958,1963,1990,2001,2031,2035,2056,2105,2168,2201,2223,2227,2231,2238,2242,2246,2251,2268,2287],{"__ignoreMap":59},[95,1848,1849],{"class":97,"line":98},[95,1850,1851],{"class":101},"// scripts/generate-sitemap.mjs\n",[95,1853,1854,1856,1858,1861,1863,1866,1868,1870,1872,1874],{"class":97,"line":105},[95,1855,278],{"class":112},[95,1857,281],{"class":108},[95,1859,1860],{"class":284}," readdirSync",[95,1862,370],{"class":108},[95,1864,1865],{"class":284}," writeFileSync",[95,1867,288],{"class":108},[95,1869,291],{"class":112},[95,1871,373],{"class":294},[95,1873,1720],{"class":298},[95,1875,1702],{"class":294},[95,1877,1878,1880,1882,1885,1887,1889,1891,1893,1895,1898],{"class":97,"line":119},[95,1879,278],{"class":112},[95,1881,281],{"class":108},[95,1883,1884],{"class":284}," join",[95,1886,370],{"class":108},[95,1888,361],{"class":284},[95,1890,288],{"class":108},[95,1892,291],{"class":112},[95,1894,373],{"class":294},[95,1896,1897],{"class":298},"path",[95,1899,1702],{"class":294},[95,1901,1902],{"class":97,"line":134},[95,1903,311],{"emptyLinePlaceholder":310},[95,1905,1906,1908,1911,1913,1915,1918],{"class":97,"line":141},[95,1907,816],{"class":321},[95,1909,1910],{"class":284}," SITE_URL",[95,1912,358],{"class":108},[95,1914,373],{"class":294},[95,1916,1917],{"class":298},"https://log.eurekapu.com",[95,1919,1702],{"class":294},[95,1921,1922,1924,1927,1929,1931,1933,1936,1938,1941,1944,1946,1949,1951],{"class":97,"line":151},[95,1923,816],{"class":321},[95,1925,1926],{"class":284}," DIST_DIR",[95,1928,358],{"class":108},[95,1930,361],{"class":328},[95,1932,364],{"class":108},[95,1934,1935],{"class":284},"process",[95,1937,398],{"class":108},[95,1939,1940],{"class":328},"cwd",[95,1942,1943],{"class":108},"(),",[95,1945,373],{"class":294},[95,1947,1948],{"class":298},"dist",[95,1950,379],{"class":294},[95,1952,1953],{"class":108},")\n",[95,1955,1956],{"class":97,"line":385},[95,1957,311],{"emptyLinePlaceholder":310},[95,1959,1960],{"class":97,"line":427},[95,1961,1962],{"class":101},"// distディレクトリから全HTMLファイルを検出\n",[95,1964,1965,1968,1971,1973,1976,1978,1981,1983,1986,1988],{"class":97,"line":464},[95,1966,1967],{"class":321},"function",[95,1969,1970],{"class":328}," getAllRoutes",[95,1972,364],{"class":108},[95,1974,1975],{"class":284},"dir",[95,1977,370],{"class":108},[95,1979,1980],{"class":284}," baseRoute",[95,1982,358],{"class":108},[95,1984,1985],{"class":294}," ''",[95,1987,504],{"class":108},[95,1989,347],{"class":108},[95,1991,1992,1994,1997,1999],{"class":97,"line":513},[95,1993,1016],{"class":321},[95,1995,1996],{"class":284}," routes",[95,1998,358],{"class":108},[95,2000,1140],{"class":108},[95,2002,2003,2005,2008,2010,2012,2014,2016,2018,2020,2023,2025,2028],{"class":97,"line":519},[95,2004,1016],{"class":321},[95,2006,2007],{"class":284}," entries",[95,2009,358],{"class":108},[95,2011,1860],{"class":328},[95,2013,364],{"class":108},[95,2015,1975],{"class":284},[95,2017,370],{"class":108},[95,2019,281],{"class":108},[95,2021,2022],{"class":548}," withFileTypes",[95,2024,1101],{"class":108},[95,2026,2027],{"class":112}," true",[95,2029,2030],{"class":108}," })\n",[95,2032,2033],{"class":97,"line":525},[95,2034,311],{"emptyLinePlaceholder":310},[95,2036,2037,2040,2042,2044,2047,2050,2052,2054],{"class":97,"line":530},[95,2038,2039],{"class":112},"  for",[95,2041,570],{"class":108},[95,2043,816],{"class":321},[95,2045,2046],{"class":284}," entry",[95,2048,2049],{"class":321}," of",[95,2051,2007],{"class":284},[95,2053,504],{"class":108},[95,2055,347],{"class":108},[95,2057,2058,2061,2063,2066,2068,2071,2073,2076,2079,2081,2083,2086,2088,2091,2093,2095,2098,2100,2103],{"class":97,"line":545},[95,2059,2060],{"class":112},"    if",[95,2062,570],{"class":108},[95,2064,2065],{"class":284},"entry",[95,2067,398],{"class":108},[95,2069,2070],{"class":328},"isDirectory",[95,2072,979],{"class":108},[95,2074,2075],{"class":321}," &&",[95,2077,2078],{"class":321}," !",[95,2080,2065],{"class":284},[95,2082,398],{"class":108},[95,2084,2085],{"class":284},"name",[95,2087,398],{"class":108},[95,2089,2090],{"class":328},"startsWith",[95,2092,364],{"class":108},[95,2094,379],{"class":294},[95,2096,2097],{"class":298},"_",[95,2099,379],{"class":294},[95,2101,2102],{"class":108},"))",[95,2104,347],{"class":108},[95,2106,2107,2110,2112,2115,2118,2121,2123,2126,2128,2130,2132,2134,2136,2138,2141,2144,2146,2149,2151,2154,2156,2158,2160,2162,2164,2166],{"class":97,"line":555},[95,2108,2109],{"class":284},"      routes",[95,2111,398],{"class":108},[95,2113,2114],{"class":328},"push",[95,2116,2117],{"class":108},"(...",[95,2119,2120],{"class":328},"getAllRoutes",[95,2122,364],{"class":108},[95,2124,2125],{"class":328},"join",[95,2127,364],{"class":108},[95,2129,1975],{"class":284},[95,2131,370],{"class":108},[95,2133,2046],{"class":284},[95,2135,398],{"class":108},[95,2137,2085],{"class":284},[95,2139,2140],{"class":108},"),",[95,2142,2143],{"class":294}," `",[95,2145,473],{"class":112},[95,2147,2148],{"class":298},"baseRoute",[95,2150,507],{"class":112},[95,2152,2153],{"class":298},"/",[95,2155,473],{"class":112},[95,2157,2065],{"class":298},[95,2159,398],{"class":108},[95,2161,2085],{"class":298},[95,2163,507],{"class":112},[95,2165,666],{"class":294},[95,2167,1775],{"class":108},[95,2169,2170,2173,2176,2179,2181,2183,2185,2187,2190,2192,2195,2197,2199],{"class":97,"line":579},[95,2171,2172],{"class":108},"    }",[95,2174,2175],{"class":112}," else",[95,2177,2178],{"class":112}," if",[95,2180,570],{"class":108},[95,2182,2065],{"class":284},[95,2184,398],{"class":108},[95,2186,2085],{"class":284},[95,2188,2189],{"class":321}," ===",[95,2191,373],{"class":294},[95,2193,2194],{"class":298},"index.html",[95,2196,379],{"class":294},[95,2198,504],{"class":108},[95,2200,347],{"class":108},[95,2202,2203,2205,2207,2209,2211,2213,2215,2217,2219,2221],{"class":97,"line":598},[95,2204,2109],{"class":284},[95,2206,398],{"class":108},[95,2208,2114],{"class":328},[95,2210,364],{"class":108},[95,2212,2148],{"class":284},[95,2214,632],{"class":321},[95,2216,373],{"class":294},[95,2218,2153],{"class":298},[95,2220,379],{"class":294},[95,2222,1953],{"class":108},[95,2224,2225],{"class":97,"line":616},[95,2226,693],{"class":108},[95,2228,2229],{"class":97,"line":638},[95,2230,699],{"class":108},[95,2232,2233,2235],{"class":97,"line":647},[95,2234,430],{"class":112},[95,2236,2237],{"class":284}," routes\n",[95,2239,2240],{"class":97,"line":653},[95,2241,522],{"class":108},[95,2243,2244],{"class":97,"line":690},[95,2245,311],{"emptyLinePlaceholder":310},[95,2247,2248],{"class":97,"line":696},[95,2249,2250],{"class":101},"// サイトマップXMLを生成\n",[95,2252,2253,2255,2257,2259,2261,2263,2266],{"class":97,"line":702},[95,2254,816],{"class":321},[95,2256,1996],{"class":284},[95,2258,358],{"class":108},[95,2260,1970],{"class":328},[95,2262,364],{"class":108},[95,2264,2265],{"class":284},"DIST_DIR",[95,2267,1953],{"class":108},[95,2269,2271,2273,2276,2278,2281,2283,2285],{"class":97,"line":2270},25,[95,2272,816],{"class":321},[95,2274,2275],{"class":284}," sitemap",[95,2277,358],{"class":108},[95,2279,2280],{"class":328}," generateSitemap",[95,2282,364],{"class":108},[95,2284,585],{"class":284},[95,2286,1953],{"class":108},[95,2288,2290,2293,2295,2297,2299,2301,2303,2305,2308,2310,2312,2314],{"class":97,"line":2289},26,[95,2291,2292],{"class":328},"writeFileSync",[95,2294,364],{"class":108},[95,2296,2125],{"class":328},[95,2298,364],{"class":108},[95,2300,2265],{"class":284},[95,2302,370],{"class":108},[95,2304,373],{"class":294},[95,2306,2307],{"class":298},"sitemap.xml",[95,2309,379],{"class":294},[95,2311,2140],{"class":108},[95,2313,2275],{"class":284},[95,2315,1953],{"class":108},[50,2317,2321],{"className":2318,"code":2319,"language":2320,"meta":59,"style":59},"language-json shiki shiki-themes vitesse-light vitesse-light","// package.json\n{\n  \"scripts\": {\n    \"postgenerate\": \"node scripts/fix-routes.mjs && node scripts/generate-sitemap.mjs\"\n  }\n}\n","json",[57,2322,2323,2328,2333,2348,2368,2372],{"__ignoreMap":59},[95,2324,2325],{"class":97,"line":98},[95,2326,2327],{"class":101},"// package.json\n",[95,2329,2330],{"class":97,"line":105},[95,2331,2332],{"class":108},"{\n",[95,2334,2335,2339,2342,2344,2346],{"class":97,"line":119},[95,2336,2338],{"class":2337},"sqvqQ","  \"",[95,2340,2341],{"class":548},"scripts",[95,2343,302],{"class":2337},[95,2345,1101],{"class":108},[95,2347,347],{"class":108},[95,2349,2350,2353,2356,2358,2360,2362,2365],{"class":97,"line":134},[95,2351,2352],{"class":2337},"    \"",[95,2354,2355],{"class":548},"postgenerate",[95,2357,302],{"class":2337},[95,2359,1101],{"class":108},[95,2361,295],{"class":294},[95,2363,2364],{"class":298},"node scripts/fix-routes.mjs && node scripts/generate-sitemap.mjs",[95,2366,2367],{"class":294},"\"\n",[95,2369,2370],{"class":97,"line":141},[95,2371,699],{"class":108},[95,2373,2374],{"class":97,"line":151},[95,2375,522],{"class":108},[43,2377,2378],{"id":2378},"教訓",[160,2380,2381,2386],{},[25,2382,2383,2385],{},[57,2384,1416],{},"はSSR/ハイブリッドモードでは動作するが、完全な静的生成では問題がある",[25,2387,2388],{},"Cloudflare Pages Staticプリセット使用時は、カスタムスクリプトでサイトマップを生成するのが確実",[14,2390,2392],{"id":2391},"他の選択肢参考","他の選択肢（参考）",[43,2394,2396],{"id":2395},"選択肢b-インデックスから除外","選択肢B: インデックスから除外",[18,2398,2399,2402],{},[57,2400,2401],{},"robots.txt"," で除外する方法。実装変更不要だが、検索で見つからなくなる。",[50,2404,2408],{"className":2405,"code":2406,"language":2407,"meta":59,"style":59},"language-txt shiki shiki-themes vitesse-light vitesse-light","User-Agent: *\nDisallow: /coding-standards/viewer/rule-\n","txt",[57,2409,2410,2415],{"__ignoreMap":59},[95,2411,2412],{"class":97,"line":98},[95,2413,2414],{},"User-Agent: *\n",[95,2416,2417],{"class":97,"line":105},[95,2418,2419],{},"Disallow: /coding-standards/viewer/rule-\n",[43,2421,2423],{"id":2422},"選択肢c-動的ルートを廃止","選択肢C: 動的ルートを廃止",[18,2425,2426],{},"一覧ページのみに集約。シンプルだが直リンク不可。",[14,2428,2429],{"id":2429},"調査で判明した追加事項",[43,2431,2432],{"id":2432},"サイトマップの状態",[160,2434,2435,2443,2452,2458],{},[25,2436,2437,453,2440,2442],{},[28,2438,2439],{},"生成方法",[57,2441,1416],{}," v7で自動生成",[25,2444,2445,453,2448,2451],{},[28,2446,2447],{},"更新タイミング",[57,2449,2450],{},"git push"," → GitHub Actions → ビルド時に自動更新",[25,2453,2454,2457],{},[28,2455,2456],{},"現在のURL数",": 177件",[25,2459,2460,2463],{},[28,2461,2462],{},"最終更新",": 2025-12-18",[43,2465,2466],{"id":2466},"インデックス状況",[160,2468,2469,2474,2480],{},[25,2470,2471,2457],{},[28,2472,2473],{},"サイトマップ登録",[25,2475,2476,2479],{},[28,2477,2478],{},"実際のインデックス",": 29件",[25,2481,2482,2485],{},[28,2483,2484],{},"差異の原因",": 以下の複合要因",[14,2487,2488],{"id":2488},"インデックス数が少ない問題の分析",[43,2490,2491],{"id":2491},"考えられる原因",[2493,2494,2495,2510],"table",{},[2496,2497,2498],"thead",{},[2499,2500,2501,2504,2507],"tr",{},[2502,2503,62],"th",{},[2502,2505,2506],{},"説明",[2502,2508,2509],{},"対処",[2511,2512,2513,2527,2540,2553,2565],"tbody",{},[2499,2514,2515,2521,2524],{},[2516,2517,2518],"td",{},[28,2519,2520],{},"クロール遅延",[2516,2522,2523],{},"新しいサイトはクロール頻度が低い",[2516,2525,2526],{},"待つ（数週間〜数ヶ月）",[2499,2528,2529,2534,2537],{},[2516,2530,2531],{},[28,2532,2533],{},"薄いコンテンツ",[2516,2535,2536],{},"内容が少ないページは優先度が低い",[2516,2538,2539],{},"コンテンツを充実させる",[2499,2541,2542,2547,2550],{},[2516,2543,2544],{},[28,2545,2546],{},"重複コンテンツ",[2516,2548,2549],{},"類似ページがあると除外される",[2516,2551,2552],{},"canonical設定を確認",[2499,2554,2555,2560,2563],{},[2516,2556,2557],{},[28,2558,2559],{},"クロールバジェット",[2516,2561,2562],{},"大規模サイトでない限り問題なし",[2516,2564,499],{},[2499,2566,2567,2572,2575],{},[2516,2568,2569],{},[28,2570,2571],{},"noindex設定",[2516,2573,2574],{},"意図せずnoindexが設定されている",[2516,2576,2577],{},"確認が必要",[43,2579,2581],{"id":2580},"googleのインデックス処理","Googleのインデックス処理",[50,2583,2586],{"className":2584,"code":2585,"language":55},[53],"サイトマップ送信 → クロール予約 → クロール実行 → 品質評価 → インデックス登録\n                    ↓                              ↓\n               数日〜数週間                    品質が低いと除外\n",[57,2587,2585],{"__ignoreMap":59},[18,2589,2590,2593],{},[28,2591,2592],{},"重要",": サイトマップに登録 ≠ インデックスに登録",[160,2595,2596,2599,2602],{},[25,2597,2598],{},"サイトマップはGoogleへの「クロールしてほしいURLリスト」",[25,2600,2601],{},"実際にインデックスされるかはGoogleの品質判断による",[25,2603,2604],{},"新しいサイトは数週間〜数ヶ月かけて徐々にインデックスされる",[43,2606,2607],{"id":2607},"対処方法",[22,2609,2610,2616,2622,2628],{},[25,2611,2612,2615],{},[28,2613,2614],{},"待つ",": 新しいコンテンツは時間がかかる（数週間〜数ヶ月）",[25,2617,2618,2621],{},[28,2619,2620],{},"サイトマップ再送信",": デプロイ後にSearch Consoleで再送信",[25,2623,2624,2627],{},[28,2625,2626],{},"URL検査",": 個別URLをSearch Consoleで検査・インデックス登録リクエスト",[25,2629,2630,2633],{},[28,2631,2632],{},"内部リンク強化",": トップページや人気ページからリンクを張る",[43,2635,2636],{"id":2636},"期待される改善",[18,2638,2639],{},"今回のSSG対応により：",[160,2641,2642,2648,2654],{},[25,2643,2644,2647],{},[28,2645,2646],{},"coding-standards",": 158ページが新たにインデックス対象に",[25,2649,2650,2653],{},[28,2651,2652],{},"コンテンツ品質",": 静的HTMLで完全なコンテンツが提供される",[25,2655,2656,2659],{},[28,2657,2658],{},"メタデータ",": title/descriptionが正しく設定される",[14,2661,2662],{"id":2662},"次のアクション",[22,2664,2667,2676,2682,2688,2694,2700],{"className":2665},[2666],"contains-task-list",[25,2668,2671,2675],{"className":2669},[2670],"task-list-item",[2672,2673],"input",{"checked":310,"disabled":310,"type":2674},"checkbox"," coding-standardsのプリレンダリング実装（完了）",[25,2677,2679,2681],{"className":2678},[2670],[2672,2680],{"checked":310,"disabled":310,"type":2674}," カスタムサイトマップ生成スクリプト作成（完了）",[25,2683,2685,2687],{"className":2684},[2670],[2672,2686],{"disabled":310,"type":2674}," デプロイして本番環境に反映",[25,2689,2691,2693],{"className":2690},[2670],[2672,2692],{"disabled":310,"type":2674}," Search Consoleでサイトマップを再送信",[25,2695,2697,2699],{"className":2696},[2670],[2672,2698],{"disabled":310,"type":2674}," 1〜2週間後にインデックス状況を再確認",[25,2701,2703,2705],{"className":2702},[2670],[2672,2704],{"disabled":310,"type":2674}," 必要に応じて個別URLの検査・登録リクエスト",[14,2707,2708],{"id":2708},"変更したファイル一覧",[2493,2710,2711,2721],{},[2496,2712,2713],{},[2499,2714,2715,2718],{},[2502,2716,2717],{},"ファイル",[2502,2719,2720],{},"変更内容",[2511,2722,2723,2735,2746,2756],{},[2499,2724,2725,2730],{},[2516,2726,2727],{},[57,2728,2729],{},"nuxt.config.ts",[2516,2731,2732,2734],{},[57,2733,561],{}," hookでプリレンダリングルートを動的追加",[2499,2736,2737,2741],{},[2516,2738,2739],{},[57,2740,1306],{},[2516,2742,2743,2745],{},[57,2744,166],{},"削除、JSONを直接import、SSG対応",[2499,2747,2748,2753],{},[2516,2749,2750],{},[57,2751,2752],{},"scripts/generate-sitemap.mjs",[2516,2754,2755],{},"新規作成: カスタムサイトマップ生成",[2499,2757,2758,2763],{},[2516,2759,2760],{},[57,2761,2762],{},"package.json",[2516,2764,2765,2767],{},[57,2766,2355],{},"にサイトマップ生成を追加",[14,2769,2770],{"id":2770},"参考リンク",[160,2772,2773,2782,2788],{},[25,2774,2775],{},[2776,2777,2781],"a",{"href":2778,"rel":2779},"https://nuxt.com/docs/getting-started/prerendering",[2780],"nofollow","Nuxt Prerendering",[25,2783,2784],{},[2776,2785,1416],{"href":2786,"rel":2787},"https://sitemap.nuxtjs.org/",[2780],[25,2789,2790],{},[2776,2791,2794],{"href":2792,"rel":2793},"https://support.google.com/webmasters/answer/7440203",[2780],"Google Search Console ヘルプ",[2796,2797,2798],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .sG7-3, html code.shiki .sG7-3{--shiki-default:#393A34;--shiki-dark:#393A34}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 .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sSkh3, html code.shiki .sSkh3{--shiki-default:#2E8F82;--shiki-dark:#2E8F82}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}html pre.shiki code .sqvqQ, html code.shiki .sqvqQ{--shiki-default:#99841877;--shiki-dark:#99841877}",{"title":59,"searchDepth":105,"depth":105,"links":2800},[2801,2802,2807,2811,2815,2822,2828,2832,2836,2842,2843,2844],{"id":16,"depth":105,"text":16},{"id":40,"depth":105,"text":41,"children":2803},[2804,2805,2806],{"id":45,"depth":119,"text":45},{"id":62,"depth":119,"text":62},{"id":176,"depth":119,"text":176},{"id":185,"depth":105,"text":186,"children":2808},[2809,2810],{"id":189,"depth":119,"text":45},{"id":201,"depth":119,"text":201},{"id":224,"depth":105,"text":225,"children":2812},[2813,2814],{"id":228,"depth":119,"text":45},{"id":237,"depth":119,"text":62},{"id":246,"depth":105,"text":247,"children":2816},[2817,2818,2819,2820,2821],{"id":250,"depth":119,"text":251},{"id":257,"depth":119,"text":257},{"id":1065,"depth":119,"text":1066},{"id":1320,"depth":119,"text":1321},{"id":1372,"depth":119,"text":1372},{"id":1407,"depth":105,"text":1408,"children":2823},[2824,2825,2826,2827],{"id":1411,"depth":119,"text":1411},{"id":1459,"depth":119,"text":1460},{"id":1835,"depth":119,"text":1836},{"id":2378,"depth":119,"text":2378},{"id":2391,"depth":105,"text":2392,"children":2829},[2830,2831],{"id":2395,"depth":119,"text":2396},{"id":2422,"depth":119,"text":2423},{"id":2429,"depth":105,"text":2429,"children":2833},[2834,2835],{"id":2432,"depth":119,"text":2432},{"id":2466,"depth":119,"text":2466},{"id":2488,"depth":105,"text":2488,"children":2837},[2838,2839,2840,2841],{"id":2491,"depth":119,"text":2491},{"id":2580,"depth":119,"text":2581},{"id":2607,"depth":119,"text":2607},{"id":2636,"depth":119,"text":2636},{"id":2662,"depth":105,"text":2662},{"id":2708,"depth":105,"text":2708},{"id":2770,"depth":105,"text":2770},null,"Search Consoleで報告された404エラーとインデックス登録数の問題を調査・分析","md",{},"/search-console-404-investigation",false,"2025-12-18T00:00:00.000Z",{"title":5,"description":2846},"2025-12/2025-12-18/search-console-404-investigation",[2855,2856,2857,2858],"SEO","Search Console","Nuxt","SSG","-UKjEI-Ob0eOXbAn4tookpSs7bxuu7vI-Qd8dgqHwl0",[],[2862,2866,2870,2874,2878],{"title":2863,"path":2864,"publishedAt":2865},"非公開記事一覧をGoogleにインデックスさせない仕組みを点検した話","/unpublished-noindex","2026-06-01T00:00:00.000Z",{"title":2867,"path":2868,"publishedAt":2869},"Google Search Console 404エラーの原因：Nuxt SSGのcrawlLinksで発見されないページ","/gsc-404-ssg-issue","2026-01-06T00:00:00.000Z",{"title":2871,"path":2872,"publishedAt":2873},"Google Search Consoleでインデックス率が低い問題の調査","/google-index-improvement","2026-01-04T00:00:00.000Z",{"title":2875,"path":2876,"publishedAt":2877},"Search Console を調べ直したら「伸びていない」が「4割落ちていた」に変わった — 日記の noindex 提案に待ったをかけた日","/gsc-review-noindex-rethink","2026-07-28T00:00:00.000Z",{"title":2879,"path":2880,"publishedAt":2881},"2026年7月19日の開発日記 - 朝に足した内部リンクが夕方のビルドを3倍遅くしていた","/2026-07-19-diary","2026-07-19T00:00:00.000Z","https://log.eurekapu.com/og/blog/search-console-404-investigation.png?v=2025-12-18T00%3A00%3A00.000Z&title=Google%20Search%20Console%20404%E3%82%A8%E3%83%A9%E3%83%BC%E8%AA%BF%E6%9F%BB&author=Kei%20Komatsu&sig=9522512041e2347b",1785552290993]