Astro 7がRustベースのSätteri markdownエンジンに切り替わったことで、数式、見出しのアンカー、カスタム設定に依存しているサイトにとって、スムーズなアップグレードになるはずが、3重の悪夢へと変わってしまいました。インライン数式は依然として動作しますが、ディスプレイ数式(display-math)ブロックはプレーンテキストのコードスニペットとして表示され、見出しのIDは消失し、Astroの設定に加えた追加オプションはすべて黙って無視されます。以前のAstroリリースから移行する開発者は、プラグインを書き直すか、ページが壊れるリスクを負う必要があります。
なぜこの変更が重要なのか
新しいエンジンは、ユーザーが提供するプラグインよりも前に組み込みの構文ハイライターを実行し、トップレベルの構成フィールドを3つしか受け付けません。これらの仕様は、ほとんどのAstroプロジェクトが機能を追加する方法と衝突します。具体的には、ハイライトの後に実行されることを前提としたremark (MDAST) や rehype (HAST) プラグインの使用や、基盤となるmarkdownパーサーに渡される寛容な設定オブジェクトの使用といった方法です。
その影響は、LaTeXスタイルの数式と通常のコンテンツを混在させているあらゆるページに現れます。インライン数式 ($a+b$) は問題なくレンダリングされますが、ディスプレイブロック ($$a+b$$) は <pre> タグで囲まれ、整形された数式ではなく生のマークアップが表示されてしまいます。目次リンクやディープリンクを支える見出しアンカーは消失します。これは、ID生成プラグインが組み込みのIDハンドラーよりも前に実行されるため、autolinkプラグインが紐付ける対象がなくなってしまうからです。shikiConfig オブジェクトを使用してShiki構文ハイライターを微調整しようとした開発者は、その設定が跡形もなく消えていることに気づくでしょう。
技術的な修正方法
1. ハイライトの前に数式をレンダリングする
根本的な原因は処理の順序にあります。Sätteriのハイライターが最初にテキストを占有し、数式ブロックをプレーンなコードとして分類してしまうのです。数式を正しく扱うには、処理をMDASTレイヤー(HTMLになる前のmarkdownを表す抽象構文木)に移行してください。HASTレベルの数式プラグインをMDAST相当のものに置き換え、ハイライターのステップの前に実行します。具体的には、remark-math プラグインをmarkdownパース段階にフックするバージョンに交換し、すでに変換された数式ノードに対してハイライターが動作するようにします。
2. 見出しIDプラグインの順序を入れ替える
見出しIDは組み込みのプラグインによって生成されますが、現在はユーザープラグインの後に実行されます。カスタムのIDまたはslug生成器をプラグインリストの最上位に移動し、最初に実行されるようにしてください。アンカーリンクを復元するための典型的なシーケンスは以下の通りです。
- slug/ID プラグイン
- autolink プラグイン
- その他のremarkプラグイン
早期にIDが配置されることで、autolinkプラグインが期待通りの <a> 要素を付与できるようになり、目次が正しいセクションを指すようになります。
3. Sätteriの厳格な設定スキーマに従う
Sätteriは、Astroのmarkdown設定において3つのフィールドのみを認識します。shikiConfig などのそれ以外の設定は、黙って破棄されます。カスタムテーマやハイライターの微調整を維持するには、それらの設定をAstro設定階層内の適切なレベルに移動してください。
クイック置換ガイド
従来のAstro markdownスタックを移植している場合は、古いremarkプラグインをSätteriが理解できる新しい機能フラグに置き換えてください。
remark-gfm→features.gfmremark-frontmatter→features.frontmatterremark-math→features.mathremark-directive→features.directiveremark-smartypants→features.smartPunctuationremark-wiki-link→features.wikilinks
これらのフラグを使用すると、個別のプラグインをロードすることなく、同じ機能を利用できます。
Sätteriでプラグインを正常に動作させるためのルール
- シングルパスのみ – プラグインはツリーを一度しか走査しません。パイプラインの後半で作成されたノードを再度訪問することはできません。
- 状態のためのファクトリ – ページ間でのデータ漏洩を防ぐため、ページごとに新しい状態オブジェクトを構築してください。
- 不変(Immutable)なノード – 変更が必要な場合は新しいノードを返してください。既存のノードを直接変更(mutate)すると、後続の処理ステップが壊れる可能性があります。
- ルートフラグメント禁止 – トップレベルのフラグメントノードを作成するのではなく、提供されている挿入ヘルパーを使用して兄弟ノードを挿入してください。
既存のプラグインを適応させる際は、READMEの例示された出力に頼らないでください。元のプラグインのHTMLをレンダリングしてそのマークアップをキャプチャし、それをSätteri互換バージョンの基準点として使用してください。
まとめ
Astro 7のSätteriエンジンは高速化をもたらしますが、Markdown処理チェーンの順序変更を余儀なくします。具体的には、MDASTレベルでの数式レンダリング、heading-IDプラグインの先頭への配置、そして設定を許可された3つのフィールドのみに限定することが必要です。フィーチャーフラグのマッピングに従い、single-passおよびimmutable-nodeのルールを遵守することで、サイトが依存している数式、アンカー、カスタムテーマを復元できます。初期段階での工数は必要ですが、その見返りとして、より予測可能で高速なMarkdownパイプラインが手に入ります。
