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生成器をプラグインリストの最上位に移動し、最初に実行されるようにしてください。アンカーリンクを復元するための典型的なシーケンスは以下の通りです。

  1. slug/ID プラグイン
  2. autolink プラグイン
  3. その他のremarkプラグイン

早期にIDが配置されることで、autolinkプラグインが期待通りの <a> 要素を付与できるようになり、目次が正しいセクションを指すようになります。

3. Sätteriの厳格な設定スキーマに従う

Sätteriは、Astroのmarkdown設定において3つのフィールドのみを認識します。shikiConfig などのそれ以外の設定は、黙って破棄されます。カスタムテーマやハイライターの微調整を維持するには、それらの設定をAstro設定階層内の適切なレベルに移動してください。

クイック置換ガイド

従来のAstro markdownスタックを移植している場合は、古いremarkプラグインをSätteriが理解できる新しい機能フラグに置き換えてください。

  • remark-gfmfeatures.gfm
  • remark-frontmatterfeatures.frontmatter
  • remark-mathfeatures.math
  • remark-directivefeatures.directive
  • remark-smartypantsfeatures.smartPunctuation
  • remark-wiki-linkfeatures.wikilinks

これらのフラグを使用すると、個別のプラグインをロードすることなく、同じ機能を利用できます。

Sätteriでプラグインを正常に動作させるためのルール

  • シングルパスのみ – プラグインはツリーを一度しか走査しません。パイプラインの後半で作成されたノードを再度訪問することはできません。
  • 状態のためのファクトリ – ページ間でのデータ漏洩を防ぐため、ページごとに新しい状態オブジェクトを構築してください。
  • 不変(Immutable)なノード – 変更が必要な場合は新しいノードを返してください。既存のノードを直接変更(mutate)すると、後続の処理ステップが壊れる可能性があります。
  • ルートフラグメント禁止 – トップレベルのフラグメントノードを作成するのではなく、提供されている挿入ヘルパーを使用して兄弟ノードを挿入してください。

既存のプラグインを適応させる際は、READMEの例示された出力に頼らないでください。元のプラグインのHTMLをレンダリングしてそのマークアップをキャプチャし、それをSätteri互換バージョンの基準点として使用してください。

まとめ

Astro 7のSätteriエンジンは高速化をもたらしますが、Markdown処理チェーンの順序変更を余儀なくします。具体的には、MDASTレベルでの数式レンダリング、heading-IDプラグインの先頭への配置、そして設定を許可された3つのフィールドのみに限定することが必要です。フィーチャーフラグのマッピングに従い、single-passおよびimmutable-nodeのルールを遵守することで、サイトが依存している数式、アンカー、カスタムテーマを復元できます。初期段階での工数は必要ですが、その見返りとして、より予測可能で高速なMarkdownパイプラインが手に入ります。