[{"data":1,"prerenderedAt":985},["ShallowReactive",2],{"content-/nuxt-content-search-mdc-ast-fix":3,"all-pages-for-dir":963,"related-/nuxt-content-search-mdc-ast-fix":964,"og-image-/nuxt-content-search-mdc-ast-fix":984},{"id":4,"title":5,"body":6,"category":946,"concepts":946,"description":947,"extension":948,"meta":949,"navigation":228,"ogImage":946,"path":950,"project_name":946,"published":951,"publishedAt":952,"seo":953,"source":946,"stem":954,"tags":955,"todo":946,"unpublished":951,"updatedAt":946,"__hash__":962},"pages/2025-11/2025-11-01/nuxt-content-search-mdc-ast-fix.md","Nuxt Content検索機能のMDC AST対応修正",{"type":7,"value":8,"toc":923},"minimark",[9,13,17,21,38,41,44,49,61,69,73,80,157,163,167,170,280,287,294,297,303,306,670,673,735,738,741,794,797,818,821,825,836,840,863,866,870,873,884,887,898,901,919],[10,11,5],"h1",{"id":12},"nuxt-content検索機能のmdc-ast対応修正",[14,15,16],"h2",{"id":16},"問題",[18,19,20],"p",{},"検索ページで以下の問題が発生していました：",[22,23,24,32],"ul",{},[25,26,27,31],"li",{},[28,29,30],"strong",{},"「SEO」で検索",": タイトルに含まれているのに0件",[25,33,34,37],{},[28,35,36],{},"「赤字」で検索",": 本文に何度も出現しているのに0件",[18,39,40],{},"一部のキーワード（「Excel」「繰越欠損金」など）は検索できるが、他のキーワードは検索できない状態でした。",[14,42,43],{"id":43},"原因調査",[45,46,48],"h3",{"id":47},"_1-flexsearchの設定確認","1. FlexSearchの設定確認",[18,50,51,52,56,57,60],{},"最初は FlexSearch の ",[53,54,55],"code",{},"tokenize: 'forward'"," が短い単語に対応していないと考え、",[53,58,59],{},"tokenize: 'full'"," に変更しました。",[22,62,63,66],{},[25,64,65],{},"✅ 「SEO」が検索可能になった",[25,67,68],{},"❌ 「赤字」はまだ0件",[45,70,72],{"id":71},"_2-本文抽出の問題を発見","2. 本文抽出の問題を発見",[18,74,75,76,79],{},"デバッグログで ",[53,77,78],{},"kurikoshi-kessonkin-calculation-module"," の記事を調査：",[81,82,87],"pre",{"className":83,"code":84,"language":85,"meta":86,"style":86},"language-javascript shiki shiki-themes vitesse-light vitesse-light","{\n  bodyLength: 115,  // わずか115文字！\n  bodyPreview: \"                   \",  // 空白ばかり\n  has赤字InBody: false\n}\n","javascript","",[53,88,89,98,119,139,151],{"__ignoreMap":86},[90,91,94],"span",{"class":92,"line":93},"line",1,[90,95,97],{"class":96},"shFtX","{\n",[90,99,101,105,108,112,115],{"class":92,"line":100},2,[90,102,104],{"class":103},"senZ8","  bodyLength",[90,106,107],{"class":96},":",[90,109,111],{"class":110},"sM54T"," 115",[90,113,114],{"class":96},",",[90,116,118],{"class":117},"sxvE3","  // わずか115文字！\n",[90,120,122,125,127,131,134,136],{"class":92,"line":121},3,[90,123,124],{"class":103},"  bodyPreview",[90,126,107],{"class":96},[90,128,130],{"class":129},"sMJiu"," \"",[90,132,133],{"class":129},"                   \"",[90,135,114],{"class":96},[90,137,138],{"class":117},"  // 空白ばかり\n",[90,140,142,145,147],{"class":92,"line":141},4,[90,143,144],{"class":103},"  has赤字InBody",[90,146,107],{"class":96},[90,148,150],{"class":149},"sHkkW"," false\n",[90,152,154],{"class":92,"line":153},5,[90,155,156],{"class":96},"}\n",[18,158,159,162],{},[28,160,161],{},"本文が正しく抽出されていない","ことが判明しました。",[45,164,166],{"id":165},"_3-ast構造の違いを発見","3. AST構造の違いを発見",[18,168,169],{},"さらに調査を進めると、ASTの構造が想定と異なることが判明しました：",[81,171,173],{"className":83,"code":172,"language":85,"meta":86,"style":86},"// 想定していた形式（従来のAST）\n{\n  type: 'text',\n  value: 'テキスト内容'\n}\n\n// 実際の形式（MDC配列形式）\n[\"h1\", {id: \"excelで繰越欠損金...\"}, \"Excelで繰越欠損金を自動計算！...\"]\n",[53,174,175,180,184,204,219,223,230,236],{"__ignoreMap":86},[90,176,177],{"class":92,"line":93},[90,178,179],{"class":117},"// 想定していた形式（従来のAST）\n",[90,181,182],{"class":92,"line":100},[90,183,97],{"class":96},[90,185,186,189,191,194,198,201],{"class":92,"line":121},[90,187,188],{"class":103},"  type",[90,190,107],{"class":96},[90,192,193],{"class":129}," '",[90,195,197],{"class":196},"sdGka","text",[90,199,200],{"class":129},"'",[90,202,203],{"class":96},",\n",[90,205,206,209,211,213,216],{"class":92,"line":141},[90,207,208],{"class":103},"  value",[90,210,107],{"class":96},[90,212,193],{"class":129},[90,214,215],{"class":196},"テキスト内容",[90,217,218],{"class":129},"'\n",[90,220,221],{"class":92,"line":153},[90,222,156],{"class":96},[90,224,226],{"class":92,"line":225},6,[90,227,229],{"emptyLinePlaceholder":228},true,"\n",[90,231,233],{"class":92,"line":232},7,[90,234,235],{"class":117},"// 実際の形式（MDC配列形式）\n",[90,237,239,242,245,247,249,251,254,258,260,262,265,267,270,272,275,277],{"class":92,"line":238},8,[90,240,241],{"class":96},"[",[90,243,244],{"class":129},"\"",[90,246,10],{"class":196},[90,248,244],{"class":129},[90,250,114],{"class":96},[90,252,253],{"class":96}," {",[90,255,257],{"class":256},"sz8Xr","id",[90,259,107],{"class":96},[90,261,130],{"class":129},[90,263,264],{"class":196},"excelで繰越欠損金...",[90,266,244],{"class":129},[90,268,269],{"class":96},"},",[90,271,130],{"class":129},[90,273,274],{"class":196},"Excelで繰越欠損金を自動計算！...",[90,276,244],{"class":129},[90,278,279],{"class":96},"]\n",[18,281,282,283,286],{},"Nuxt ContentはMDC (Markdown Components) 形式でASTを構築しており、配列形式 ",[53,284,285],{},"[\"tag\", {attributes}, ...children]"," を使用していました。",[18,288,289,290,293],{},"既存の ",[53,291,292],{},"extractTextFromAST"," 関数は従来の AST 形式しか想定しておらず、MDC 配列形式のノードからテキストを抽出できていませんでした。",[14,295,296],{"id":296},"修正内容",[45,298,300,302],{"id":299},"extracttextfromast-関数の改善",[53,301,292],{}," 関数の改善",[18,304,305],{},"3種類のノード形式に対応するよう修正しました：",[81,307,309],{"className":83,"code":308,"language":85,"meta":86,"style":86},"// ASTからテキストを再帰的に抽出\nfunction extractTextFromAST(nodes) {\n  if (!nodes || !Array.isArray(nodes)) return ''\n\n  return nodes.map(node => {\n    // 1. 文字列ノードの場合\n    if (typeof node === 'string') {\n      return node\n    }\n    \n    // 2. 配列ノード（MDC形式: [\"tag\", {attrs}, ...children]）の場合\n    if (Array.isArray(node)) {\n      // 最初の要素はタグ名、2番目は属性、3番目以降が子要素\n      const children = node.slice(2)\n      return extractTextFromAST(children)\n    }\n    \n    // 3. オブジェクトノード（従来のAST形式）の場合\n    if (node.type === 'text') {\n      return node.value || ''\n    }\n    if (node.children) {\n      return extractTextFromAST(node.children)\n    }\n    \n    return ''\n  }).join(' ')\n}\n",[53,310,311,316,338,379,383,406,411,438,446,452,459,465,486,492,519,533,538,543,549,575,591,596,613,630,635,640,648,665],{"__ignoreMap":86},[90,312,313],{"class":92,"line":93},[90,314,315],{"class":117},"// ASTからテキストを再帰的に抽出\n",[90,317,318,322,325,328,332,335],{"class":92,"line":100},[90,319,321],{"class":320},"stQ0i","function",[90,323,324],{"class":103}," extractTextFromAST",[90,326,327],{"class":96},"(",[90,329,331],{"class":330},"s4oTP","nodes",[90,333,334],{"class":96},")",[90,336,337],{"class":96}," {\n",[90,339,340,343,346,349,351,354,357,360,363,366,368,370,373,376],{"class":92,"line":121},[90,341,342],{"class":149},"  if",[90,344,345],{"class":96}," (",[90,347,348],{"class":320},"!",[90,350,331],{"class":330},[90,352,353],{"class":320}," ||",[90,355,356],{"class":320}," !",[90,358,359],{"class":330},"Array",[90,361,362],{"class":96},".",[90,364,365],{"class":103},"isArray",[90,367,327],{"class":96},[90,369,331],{"class":330},[90,371,372],{"class":96},"))",[90,374,375],{"class":149}," return",[90,377,378],{"class":129}," ''\n",[90,380,381],{"class":92,"line":141},[90,382,229],{"emptyLinePlaceholder":228},[90,384,385,388,391,393,396,398,401,404],{"class":92,"line":153},[90,386,387],{"class":149},"  return",[90,389,390],{"class":330}," nodes",[90,392,362],{"class":96},[90,394,395],{"class":103},"map",[90,397,327],{"class":96},[90,399,400],{"class":330},"node",[90,402,403],{"class":96}," =>",[90,405,337],{"class":96},[90,407,408],{"class":92,"line":225},[90,409,410],{"class":117},"    // 1. 文字列ノードの場合\n",[90,412,413,416,418,421,424,427,429,432,434,436],{"class":92,"line":232},[90,414,415],{"class":149},"    if",[90,417,345],{"class":96},[90,419,420],{"class":320},"typeof",[90,422,423],{"class":330}," node",[90,425,426],{"class":320}," ===",[90,428,193],{"class":129},[90,430,431],{"class":196},"string",[90,433,200],{"class":129},[90,435,334],{"class":96},[90,437,337],{"class":96},[90,439,440,443],{"class":92,"line":238},[90,441,442],{"class":149},"      return",[90,444,445],{"class":330}," node\n",[90,447,449],{"class":92,"line":448},9,[90,450,451],{"class":96},"    }\n",[90,453,455],{"class":92,"line":454},10,[90,456,458],{"class":457},"sG7-3","    \n",[90,460,462],{"class":92,"line":461},11,[90,463,464],{"class":117},"    // 2. 配列ノード（MDC形式: [\"tag\", {attrs}, ...children]）の場合\n",[90,466,468,470,472,474,476,478,480,482,484],{"class":92,"line":467},12,[90,469,415],{"class":149},[90,471,345],{"class":96},[90,473,359],{"class":330},[90,475,362],{"class":96},[90,477,365],{"class":103},[90,479,327],{"class":96},[90,481,400],{"class":330},[90,483,372],{"class":96},[90,485,337],{"class":96},[90,487,489],{"class":92,"line":488},13,[90,490,491],{"class":117},"      // 最初の要素はタグ名、2番目は属性、3番目以降が子要素\n",[90,493,495,498,501,504,506,508,511,513,516],{"class":92,"line":494},14,[90,496,497],{"class":320},"      const",[90,499,500],{"class":330}," children",[90,502,503],{"class":96}," =",[90,505,423],{"class":330},[90,507,362],{"class":96},[90,509,510],{"class":103},"slice",[90,512,327],{"class":96},[90,514,515],{"class":110},"2",[90,517,518],{"class":96},")\n",[90,520,522,524,526,528,531],{"class":92,"line":521},15,[90,523,442],{"class":149},[90,525,324],{"class":103},[90,527,327],{"class":96},[90,529,530],{"class":330},"children",[90,532,518],{"class":96},[90,534,536],{"class":92,"line":535},16,[90,537,451],{"class":96},[90,539,541],{"class":92,"line":540},17,[90,542,458],{"class":457},[90,544,546],{"class":92,"line":545},18,[90,547,548],{"class":117},"    // 3. オブジェクトノード（従来のAST形式）の場合\n",[90,550,552,554,556,558,560,563,565,567,569,571,573],{"class":92,"line":551},19,[90,553,415],{"class":149},[90,555,345],{"class":96},[90,557,400],{"class":330},[90,559,362],{"class":96},[90,561,562],{"class":330},"type",[90,564,426],{"class":320},[90,566,193],{"class":129},[90,568,197],{"class":196},[90,570,200],{"class":129},[90,572,334],{"class":96},[90,574,337],{"class":96},[90,576,578,580,582,584,587,589],{"class":92,"line":577},20,[90,579,442],{"class":149},[90,581,423],{"class":330},[90,583,362],{"class":96},[90,585,586],{"class":330},"value",[90,588,353],{"class":320},[90,590,378],{"class":129},[90,592,594],{"class":92,"line":593},21,[90,595,451],{"class":96},[90,597,599,601,603,605,607,609,611],{"class":92,"line":598},22,[90,600,415],{"class":149},[90,602,345],{"class":96},[90,604,400],{"class":330},[90,606,362],{"class":96},[90,608,530],{"class":330},[90,610,334],{"class":96},[90,612,337],{"class":96},[90,614,616,618,620,622,624,626,628],{"class":92,"line":615},23,[90,617,442],{"class":149},[90,619,324],{"class":103},[90,621,327],{"class":96},[90,623,400],{"class":330},[90,625,362],{"class":96},[90,627,530],{"class":330},[90,629,518],{"class":96},[90,631,633],{"class":92,"line":632},24,[90,634,451],{"class":96},[90,636,638],{"class":92,"line":637},25,[90,639,458],{"class":457},[90,641,643,646],{"class":92,"line":642},26,[90,644,645],{"class":149},"    return",[90,647,378],{"class":129},[90,649,651,654,657,659,661,663],{"class":92,"line":650},27,[90,652,653],{"class":96},"  }).",[90,655,656],{"class":103},"join",[90,658,327],{"class":96},[90,660,200],{"class":129},[90,662,193],{"class":129},[90,664,518],{"class":96},[90,666,668],{"class":92,"line":667},28,[90,669,156],{"class":96},[45,671,672],{"id":672},"対応したノード形式",[674,675,676,692],"table",{},[677,678,679],"thead",{},[680,681,682,686,689],"tr",{},[683,684,685],"th",{},"形式",[683,687,688],{},"例",[683,690,691],{},"説明",[693,694,695,709,722],"tbody",{},[680,696,697,701,706],{},[698,699,700],"td",{},"文字列",[698,702,703],{},[53,704,705],{},"\"テキスト\"",[698,707,708],{},"直接のテキストコンテンツ",[680,710,711,714,719],{},[698,712,713],{},"MDC配列",[698,715,716],{},[53,717,718],{},"[\"h1\", {id: \"...\"}, \"見出し\"]",[698,720,721],{},"Nuxt ContentのMDC形式",[680,723,724,727,732],{},[698,725,726],{},"オブジェクト",[698,728,729],{},[53,730,731],{},"{type: 'text', value: '...'}",[698,733,734],{},"従来のAST形式",[14,736,737],{"id":737},"結果",[18,739,740],{},"修正後の本文抽出結果：",[81,742,744],{"className":83,"code":743,"language":85,"meta":86,"style":86},"{\n  bodyLength: 3874,  // 115 → 3874文字に改善！\n  bodyPreview: \"Excelで繰越欠損金を自動計算！...\",\n  has赤字InBody: true  // ✅ 検出成功\n}\n",[53,745,746,750,764,778,790],{"__ignoreMap":86},[90,747,748],{"class":92,"line":93},[90,749,97],{"class":96},[90,751,752,754,756,759,761],{"class":92,"line":100},[90,753,104],{"class":103},[90,755,107],{"class":96},[90,757,758],{"class":110}," 3874",[90,760,114],{"class":96},[90,762,763],{"class":117},"  // 115 → 3874文字に改善！\n",[90,765,766,768,770,772,774,776],{"class":92,"line":121},[90,767,124],{"class":103},[90,769,107],{"class":96},[90,771,130],{"class":129},[90,773,274],{"class":196},[90,775,244],{"class":129},[90,777,203],{"class":96},[90,779,780,782,784,787],{"class":92,"line":141},[90,781,144],{"class":103},[90,783,107],{"class":96},[90,785,786],{"class":149}," true",[90,788,789],{"class":117},"  // ✅ 検出成功\n",[90,791,792],{"class":92,"line":153},[90,793,156],{"class":96},[45,795,796],{"id":796},"検索結果の改善",[22,798,799,806,812],{},[25,800,801,802,805],{},"✅ ",[28,803,804],{},"「SEO」検索",": 5件ヒット（FlexSearch の tokenize: 'full' 効果）",[25,807,801,808,811],{},[28,809,810],{},"「赤字」検索",": 1件ヒット（本文抽出の修正効果）",[25,813,801,814,817],{},[28,815,816],{},"キーワードハイライト",": スニペット内で正しく強調表示",[14,819,820],{"id":820},"学んだこと",[45,822,824],{"id":823},"_1-nuxt-content-の-ast-形式","1. Nuxt Content の AST 形式",[18,826,827,828,831,832,835],{},"Nuxt Content は MDC (Markdown Components) を使用しており、AST は配列形式 ",[53,829,830],{},"[\"tag\", {attrs}, ...children]"," で構築されます。従来の ",[53,833,834],{},"{type, value, children}"," 形式とは異なります。",[45,837,839],{"id":838},"_2-デバッグの重要性","2. デバッグの重要性",[22,841,842,848,854],{},[25,843,844,847],{},[28,845,846],{},"症状",": 一部のキーワードだけ検索できない",[25,849,850,853],{},[28,851,852],{},"仮説1",": FlexSearch の設定問題 → 一部解決",[25,855,856,859,860],{},[28,857,858],{},"仮説2",": 本文抽出の問題 → ",[28,861,862],{},"根本原因を発見",[18,864,865],{},"段階的なデバッグログの追加が問題の特定に有効でした。",[45,867,869],{"id":868},"_3-柔軟な実装","3. 柔軟な実装",[18,871,872],{},"複数の形式に対応することで、将来の変更にも強い実装になりました：",[22,874,875,878,881],{},[25,876,877],{},"MDC配列形式（現在の主要形式）",[25,879,880],{},"従来のAST形式（後方互換性）",[25,882,883],{},"文字列ノード（エッジケース対応）",[14,885,886],{"id":886},"関連ファイル",[22,888,889],{},[25,890,891,894,895,897],{},[53,892,893],{},"apps/web/app/pages/search.vue:177-205"," - ",[53,896,292],{}," 関数",[14,899,900],{"id":900},"参考",[22,902,903,912],{},[25,904,905],{},[906,907,911],"a",{"href":908,"rel":909},"https://content.nuxt.com/usage/markdown",[910],"nofollow","Nuxt Content MDC",[25,913,914],{},[906,915,918],{"href":916,"rel":917},"https://github.com/nextapps-de/flexsearch#tokenizer",[910],"FlexSearch Tokenizer Options",[920,921,922],"style",{},"html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sM54T, html code.shiki .sM54T{--shiki-default:#2F798A;--shiki-dark:#2F798A}html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}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 .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sG7-3, html code.shiki .sG7-3{--shiki-default:#393A34;--shiki-dark:#393A34}",{"title":86,"searchDepth":100,"depth":100,"links":924},[925,926,931,936,939,944,945],{"id":16,"depth":100,"text":16},{"id":43,"depth":100,"text":43,"children":927},[928,929,930],{"id":47,"depth":121,"text":48},{"id":71,"depth":121,"text":72},{"id":165,"depth":121,"text":166},{"id":296,"depth":100,"text":296,"children":932},[933,935],{"id":299,"depth":121,"text":934},"extractTextFromAST 関数の改善",{"id":672,"depth":121,"text":672},{"id":737,"depth":100,"text":737,"children":937},[938],{"id":796,"depth":121,"text":796},{"id":820,"depth":100,"text":820,"children":940},[941,942,943],{"id":823,"depth":121,"text":824},{"id":838,"depth":121,"text":839},{"id":868,"depth":121,"text":869},{"id":886,"depth":100,"text":886},{"id":900,"depth":100,"text":900},null,"MDC配列形式のASTに対応していなかった検索機能を修正し、日本語・英語の全文検索を実現","md",{},"/nuxt-content-search-mdc-ast-fix",false,"2025-11-01T00:00:00.000Z",{"title":5,"description":947},"2025-11/2025-11-01/nuxt-content-search-mdc-ast-fix",[956,957,958,959,960,961],"nuxt-content","search","MDC","AST","bug-fix","FlexSearch","JiFp6gHU82tepD1rPQzUEJfQ_CGzFjnByKn8g7fz3QU",[],[965,969,972,976,980],{"title":966,"path":967,"publishedAt":968},"Nuxt ContentでMDXが使えない理由","/nuxt-content-mdx-investigation","2025-12-16T00:00:00.000Z",{"title":970,"path":971,"publishedAt":952},"デバウンス処理と本文検索の実装ガイド","/search-implementation",{"title":973,"path":974,"publishedAt":975},"コンテンツがインデックスに表示されない問題の原因と対処","/frontmatter-issues-fix","2025-10-26T00:00:00.000Z",{"title":977,"path":978,"publishedAt":979},"マークダウン記事の$隣接**が数式化されて崩れる問題を発見、115ファイルの修正を明日に持ち越し","/dollar-sign-math-render-issue-triage","2026-07-16T00:00:00.000Z",{"title":981,"path":982,"publishedAt":983},"/blog ページの payload null 化が再発した話 — 再デプロイで直したが原因は特定できず","/blog-payload-null-rerun","2026-06-23T00:00:00.000Z","https://log.eurekapu.com/og/blog/nuxt-content-search-mdc-ast-fix.png?v=2025-11-01T00%3A00%3A00.000Z&title=Nuxt%20Content%E6%A4%9C%E7%B4%A2%E6%A9%9F%E8%83%BD%E3%81%AEMDC%20AST%E5%AF%BE%E5%BF%9C%E4%BF%AE%E6%AD%A3&author=Kei%20Komatsu&sig=c609151aa509c96d",1785654658818]