[{"data":1,"prerenderedAt":433},["ShallowReactive",2],{"content-/content-creation-mermaid-migration":3,"all-pages-for-dir":431,"og-image-/content-creation-mermaid-migration":432},{"id":4,"title":5,"body":6,"category":411,"description":412,"extension":413,"meta":414,"navigation":326,"path":415,"project_name":416,"published":417,"publishedAt":418,"seo":419,"stem":420,"tags":421,"todo":428,"updatedAt":429,"__hash__":430},"pages/2026-04/2026-04-01/content-creation-mermaid-migration.md","SVGのtext-anchor問題に61箇所対応して挫折し、Beautiful Mermaidに移行した話",{"type":7,"value":8,"toc":392},"minimark",[9,13,18,21,29,32,41,45,48,51,55,58,61,77,83,87,90,95,107,198,202,205,209,218,221,225,228,231,235,238,241,248,258,262,265,286,293,347,350,364,367,370,373,376,379,382,385,388],[10,11,12],"p",{},"朝9時にSVG図の修正を始めて、夕方5時にSVGを全削除した。8時間かけて辿り着いた結論が「捨てる」だった日の記録。",[14,15,17],"h2",{"id":16},"googlebot-2mb-html制限の記事を書いた","Googlebot 2MB HTML制限の記事を書いた",[10,19,20],{},"2026年3月31日、GoogleのGary Illyesが公式ブログで「Inside Googlebot: demystifying crawling, fetching, and the bytes we process」を公開した。Googlebotがクロールするファイルサイズに明確な上限があることを、Google自身が初めて体系的に語った記事だ。",[10,22,23,24,28],{},"HTMLは",[25,26,27],"strong",{},"非圧縮で最初の2MBまで","しか取得されない。2MBを超えた部分はインデックスされない。",[10,30,31],{},"この情報を受けて、自サイト全記事のHTMLサイズを調査した。結果、2MB超えの記事はゼロ。現時点では問題なしと確認できた。ただし、長大な記事を書く場合は意識する必要がある。",[10,33,34,35,40],{},"詳細は",[36,37,39],"a",{"href":38},"/googlebot-2mb-html-limit","Googlebot 2MB制限の記事","にまとめた。",[14,42,44],{"id":43},"claude-codeソースコード流出事件の調査","Claude Codeソースコード流出事件の調査",[10,46,47],{},"3月31日に発生したClaude Codeのソースコード流出事件を追った。複数のメディアが報道しており、npm publishのミスで内部コードが一時的に公開状態になったとされている。Claude Codeの内部プロンプトやアーキテクチャの一部が露出した。",[10,49,50],{},"ユーザーとして利用している以上、何が漏れて何が影響するのかは把握しておく必要がある。調査結果から、直接的なセキュリティリスクは限定的と判断した。",[14,52,54],{"id":53},"cpe研修記事の作成","CPE研修記事の作成",[10,56,57],{},"会計士向けの倫理研修の内容を記事化した。Google Docsに残っていた文字起こしデータを読み取り、7つのテーマに構造化して1本の記事に仕上げた。",[10,59,60],{},"作業の流れは以下の通り。",[62,63,64,68,71,74],"ol",{},[65,66,67],"li",{},"Google Docsから文字起こしデータを取得",[65,69,70],{},"話の流れを整理し、7テーマに分割（マインドセット、NOCLAR、独立性、テクノロジー、タックスプランニング、サステナビリティ、グループ監査）",[65,72,73],{},"各テーマにテーブルと図を配置",[65,75,76],{},"SVG図を6枚作成 ← ここで地獄が始まる",[10,78,34,79,40],{},[36,80,82],{"href":81},"/cpa-ethics-seminar-2025","CPE研修の記事",[14,84,86],{"id":85},"svg図の試行錯誤と挫折","SVG図の試行錯誤と挫折",[10,88,89],{},"CPE記事にフロー図やタイムラインを入れるため、インラインSVGで図を作り始めた。ここから泥沼に嵌まった。",[91,92,94],"h3",{"id":93},"問題1-text-anchor属性がmdxパーサーに消される","問題1: text-anchor属性がMDXパーサーに消される",[10,96,97,98,102,103,106],{},"MDXのパーサーがSVGの",[99,100,101],"code",{},"text-anchor","属性を認識せず、レンダリング時に属性ごと消えた。",[99,104,105],{},"text-anchor=\"middle\"","が効かないので、テキストの中央揃えが全く機能しない。",[108,109,114],"pre",{"className":110,"code":111,"language":112,"meta":113,"style":113},"language-html shiki shiki-themes vitesse-light vitesse-light","\u003C!-- MDXパーサーが text-anchor を消す -->\n\u003Ctext x=\"100\" y=\"50\" text-anchor=\"middle\">テーマ1\u003C/text>\n\u003C!-- ↓ レンダリング結果: text-anchor が消えて左寄せになる -->\n","html","",[99,115,116,125,192],{"__ignoreMap":113},[117,118,121],"span",{"class":119,"line":120},"line",1,[117,122,124],{"class":123},"sxvE3","\u003C!-- MDXパーサーが text-anchor を消す -->\n",[117,126,128,132,136,140,143,147,151,153,156,158,160,163,165,168,170,172,175,177,180,184,187,189],{"class":119,"line":127},2,[117,129,131],{"class":130},"shFtX","\u003C",[117,133,135],{"class":134},"sPqwx","text",[117,137,139],{"class":138},"s4oTP"," x",[117,141,142],{"class":130},"=",[117,144,146],{"class":145},"sMJiu","\"",[117,148,150],{"class":149},"sdGka","100",[117,152,146],{"class":145},[117,154,155],{"class":138}," y",[117,157,142],{"class":130},[117,159,146],{"class":145},[117,161,162],{"class":149},"50",[117,164,146],{"class":145},[117,166,167],{"class":138}," text-anchor",[117,169,142],{"class":130},[117,171,146],{"class":145},[117,173,174],{"class":149},"middle",[117,176,146],{"class":145},[117,178,179],{"class":130},">",[117,181,183],{"class":182},"sG7-3","テーマ1",[117,185,186],{"class":130},"\u003C/",[117,188,135],{"class":134},[117,190,191],{"class":130},">\n",[117,193,195],{"class":119,"line":194},3,[117,196,197],{"class":123},"\u003C!-- ↓ レンダリング結果: text-anchor が消えて左寄せになる -->\n",[91,199,201],{"id":200},"問題2-日本語テキストがviewboxの幅を超える","問題2: 日本語テキストがviewBoxの幅を超える",[10,203,204],{},"英語フォントの幅で設計したviewBoxに日本語テキストを入れると、文字が右端からはみ出す。viewBoxを広げると今度はレイアウト全体が崩れる。",[91,206,208],{"id":207},"_61箇所修正してまだ溢れる","61箇所修正して、まだ溢れる",[10,210,211,213,214,217],{},[99,212,101],{},"の問題を回避するため、各テキスト要素のx座標を手動で計算し直した。修正箇所は",[25,215,216],{},"61箇所","。1つずつ座標を調整して、ブラウザで確認して、また直して。",[10,219,220],{},"61箇所を直し終えて画面を確認した。まだ溢れていた。日本語テキストの幅がフォントによって変わるため、別の環境では再び崩れる。根本的に解決していない。",[91,222,224],{"id":223},"svg全削除を決断","SVG全削除を決断",[10,226,227],{},"8時間格闘した末、インラインSVGでの図表管理はMDX環境では現実的でないと判断した。全SVGファイルを削除するコミットを書いた。",[10,229,230],{},"捨てる判断が一番難しかった。「61箇所も直したのだから」というサンクコストが頭にちらついた。だが壊れた基盤の上に積み上げても、次の記事でまた同じ問題が再発する。",[14,232,234],{"id":233},"beautiful-mermaidへの移行","Beautiful Mermaidへの移行",[10,236,237],{},"SVGを捨てた後、代替手段としてBeautiful Mermaidを導入した。Mermaid記法で図を定義し、事前にSVGファイルを生成して、記事からは画像として参照する方式だ。",[91,239,240],{"id":240},"仕組み",[108,242,246],{"className":243,"code":245,"language":135},[244],"language-text","Mermaid定義（テキスト）\n  → beautiful-mermaid（CLIツール）\n    → SVGファイル生成\n      → 記事から ![alt](./diagram.svg) で参照\n",[99,247,245],{"__ignoreMap":113},[10,249,250,251,254,255,257],{},"ポイントは",[25,252,253],{},"事前生成","であること。MDXのパーサーを通さずに済むので、",[99,256,101],{},"問題は発生しない。生成されたSVGは静的ファイルとして配置するだけ。",[91,259,261],{"id":260},"_6つの図を移行","6つの図を移行",[10,263,264],{},"CPE研修記事の図を全てMermaid定義に書き直し、SVGを再生成した。",[266,267,268,271,274,277,280,283],"ul",{},[65,269,270],{},"タイムライン図（研修テーマの適用状況）",[65,272,273],{},"基準策定フロー（IESBA → JICPA → 会員）",[65,275,276],{},"NOCLAR対応フロー",[65,278,279],{},"独立性の変遷",[65,281,282],{},"タックスプランニングの分類",[65,284,285],{},"全体サマリー",[10,287,288,289,292],{},"各図は",[99,290,291],{},"div style=\"text-align:center\"","で中央寄せして配置した。",[108,294,298],{"className":295,"code":296,"language":297,"meta":113,"style":113},"language-markdown shiki shiki-themes vitesse-light vitesse-light","\u003Cdiv style=\"text-align:center\">\n\n![研修テーマの適用状況](./timeline.svg)\n\n\u003C/div>\n","markdown",[99,299,300,322,328,333,338],{"__ignoreMap":113},[117,301,302,304,308,311,313,315,318,320],{"class":119,"line":120},[117,303,131],{"class":130},[117,305,307],{"class":306},"sHkkW","div",[117,309,310],{"class":138}," style",[117,312,142],{"class":130},[117,314,146],{"class":145},[117,316,317],{"class":149},"text-align:center",[117,319,146],{"class":145},[117,321,191],{"class":130},[117,323,324],{"class":119,"line":127},[117,325,327],{"emptyLinePlaceholder":326},true,"\n",[117,329,330],{"class":119,"line":194},[117,331,332],{"class":182},"![研修テーマの適用状況](./timeline.svg)\n",[117,334,336],{"class":119,"line":335},4,[117,337,327],{"emptyLinePlaceholder":326},[117,339,341,343,345],{"class":119,"line":340},5,[117,342,186],{"class":130},[117,344,307],{"class":306},[117,346,191],{"class":130},[91,348,349],{"id":349},"学んだこと",[266,351,352,355,358,361],{},[65,353,354],{},"MDX環境でインラインSVGを使うと、パーサーとの相性問題が避けられない",[65,356,357],{},"事前生成方式なら、SVGの中身をパーサーが触らないので安全",[65,359,360],{},"Mermaid記法はテキストベースなので、Gitでの差分管理も効く",[65,362,363],{},"「直す」より「仕組みを変える」方が速いケースがある",[14,365,366],{"id":366},"summarize-meetingスキルの拡張",[10,368,369],{},"会議要約スキル（summarize-meeting）をプロジェクトにコピーし、Beautiful Mermaid対応を追加した。会議ログから図を生成する際にMermaid経由でSVGを出力できるようにした。",[10,371,372],{},"併せて、Google Meet APIの話者分離（Speaker Diarization）を調査した。結論として、REST APIだけでは話者分離は実現できない。リアルタイムストリーミングAPIが必要で、現状の即録くんの構成では対応が難しい。",[14,374,375],{"id":375},"デプロイ",[10,377,378],{},"全ての変更をまとめてCloudflare Pagesにデプロイした。Googlebot記事、CPE研修記事、Beautiful Mermaid移行後のSVG図、全てが本番環境に反映された。",[14,380,381],{"id":381},"一日の振り返り",[10,383,384],{},"この日のハイライトは間違いなくSVG→Beautiful Mermaid移行だ。8時間かけた手作業を捨てて、仕組みごと入れ替えた。結果として、今後の図表作成はMermaid定義を書くだけで済むようになった。",[10,386,387],{},"「61箇所直した」という事実は無駄ではない。MDXパーサーがSVG属性をどう扱うか、日本語テキストの幅がフォントに依存すること、これらは手を動かしたから分かった。ただ、その学びを「次も手で直す」ではなく「仕組みで回避する」に転換できたのが、この日の収穫だった。",[389,390,391],"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 .sPqwx, html code.shiki .sPqwx{--shiki-default:#B31D28;--shiki-dark:#B31D28}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 .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 .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}",{"title":113,"searchDepth":127,"depth":127,"links":393},[394,395,396,397,403,408,409,410],{"id":16,"depth":127,"text":17},{"id":43,"depth":127,"text":44},{"id":53,"depth":127,"text":54},{"id":85,"depth":127,"text":86,"children":398},[399,400,401,402],{"id":93,"depth":194,"text":94},{"id":200,"depth":194,"text":201},{"id":207,"depth":194,"text":208},{"id":223,"depth":194,"text":224},{"id":233,"depth":127,"text":234,"children":404},[405,406,407],{"id":240,"depth":194,"text":240},{"id":260,"depth":194,"text":261},{"id":349,"depth":194,"text":349},{"id":366,"depth":127,"text":366},{"id":375,"depth":127,"text":375},{"id":381,"depth":127,"text":381},"dev","インラインSVGがMDXパーサーに食われる問題を発端に、SVG全削除→Mermaid定義からSVG事前生成する方式に移行。Googlebot 2MB制限記事、CPE研修記事、Claude Codeソースコード流出調査も含む一日の記録。","md",{},"/content-creation-mermaid-migration","mdx-playground",false,"2026-04-01T00:00:00.000Z",{"title":5,"description":412},"2026-04/2026-04-01/content-creation-mermaid-migration",[422,423,424,425,426,427],"SVG","Mermaid","MDX","Beautiful Mermaid","開発日記","Claude Code","memo",null,"0Qi0YBRmHq6usCOYIJwt0hIRIf2tBSpZ2XgFeJ--LYQ",[],"https://log.eurekapu.com/favicon.svg",1775338203532]