Astro 7’s switch to the Rust-based Sätteri markdown engine is turning display-math blocks into plain code, stripping heading anchors and discarding custom markdown options – a pain point for anyone who upgraded and now sees broken equations on their site.
If you rely on LaTeX-style math, automatic heading links or bespoke markdown plugins, the upgrade can make your content unreadable and your navigation unusable, so fixing it quickly is essential.
Why the upgrade broke things
Astro now runs Sätteri as its core Markdown processor. Sätteri changes the order in which plugins are applied: it runs syntax highlighting before the HTML-AST (HAST) plugins you may have configured. That shift means three common patterns stop working:
- Display math – blocks delimited by
$$ … $$are treated as ordinary code because the highlighter runs first. - Heading anchors – plugins that generate slugs (URL-friendly IDs) and then autolink those headings no longer see the IDs, so the links are never created.
- Custom options – any extra settings you passed directly into the Sätteri processor are ignored; Astro only forwards three predefined fields.
The concrete fixes
1. Render math on the markdown-AST (MDAST) instead of the HTML-AST
Astro’s markdown pipeline has two plugin slots:
mdastPlugins– run on the parsed markdown tree before it becomes HTML.hastPlugins– run on the HTML tree after conversion.
Because the highlighter runs before hastPlugins, math gets turned into a code block. Move your math plugin to mdastPlugins.
export default {
markdown: {
mdastPlugins: [
// put remark-math (or your custom math handler) here
],
// leave hastPlugins for things that truly need HTML nodes
}
}
2. Reorder slug and autolink plugins for headings
Standard setups install a slug generator followed by an autolink plugin. In Astro, the built-in heading-ID plugin runs after your list, leaving nothing for the autolink plugin to attach to. Place the slug plugin first in the list, then the autolink plugin.
export default {
markdown: {
mdastPlugins: [
satteriSlug(), // must be first
satteriAutolinkHeadings() // runs after slug, sees IDs
]
}
}
Now each heading receives an ID and the autolink plugin can wrap it with the appropriate anchor.
3. Put extra configuration at the top level of the Astro markdown object
Astro only forwards three specific fields to the Sätteri processor. Anything you nest inside the processor (for example a shikiConfig object) gets dropped. Move those extra settings to the top level of the markdown configuration.
export default {
markdown: {
shikiConfig: { theme: 'nord' }, // top-level, will be respected
// other Astro-accepted fields …
mdastPlugins: [/* … */],
hastPlugins: [/* … */]
}
}
Quick replacement guide for common remark plugins
| Old remark plugin | New Astro feature flag |
|---|---|
remark-gfm |
features.gfm |
remark-frontmatter |
features.frontmatter |
remark-math |
features.math |
remark-directive |
features.directive |
remark-smartypants |
features.smartPunctuation |
remark-wiki-link |
features.wikilinks |
Swap the plugin name for the corresponding features.* flag in your Astro config.
Best practices when porting plugins to Sätteri
- Factory pattern – create a new plugin instance per document to avoid leaking state between pages.
- Immutable nodes – never mutate a node in place; return a fresh node object so the processor can track changes correctly.
- Insert helpers – use
ctx.insertBeforeorctx.insertAfterwhen you need to add sibling nodes, rather than splicing the tree manually.
Following these rules keeps the processor stable and prevents hard-to-track bugs.
What to watch next
Astro’s documentation still lists the old plugin order as the default, so new projects may inherit the broken behavior unintentionally. Keep an eye on upcoming Astro releases for a possible built-in fix that reorders the internal heading-ID plugin. In the meantime, the steps above are the only reliable way to restore math rendering, heading anchors and custom markdown options after moving to Astro 7.
Takeaway: Switching to Astro 7’s Sätteri engine requires moving math handling to mdastPlugins, front-loading the slug plugin before autolinks, and lifting any extra markdown settings out of the processor object; once those three adjustments are made, your site’s equations, navigation links and custom markdown features work as before.
