withastro/astro · warning
[astro] `markdown.remarkPlugins`, `markdown.rehypePlugins`,
Error message
[astro] `markdown.remarkPlugins`, `markdown.rehypePlugins`, and `markdown.remarkRehype` are deprecated. Pass them to `unified({...})` from `@astrojs/markdown-remark` directly instead. What it means
markdown.remarkPlugins, markdown.rehypePlugins, and markdown.remarkRehype are deprecated in favor of passing them to the unified({...}) processor from @astrojs/markdown-remark. While the unified processor is active, Astro still folds the legacy keys into it (plugins keep working, migration counts tracked per processor object) and prints this one-time warning.
Source
Thrown at packages/astro/src/core/config/validate.ts:108
const target = (current ?? (md.processor = unified())) as ReturnType<typeof unified>;
const counts = migratedLegacyPluginCounts.get(target.options) ?? { remark: 0, rehype: 0 };
// Only push entries past what we've already folded; mergeConfig appends, so they sit at the tail.
if (remarkPlugins.length > counts.remark) {
target.options.remarkPlugins.push(...remarkPlugins.slice(counts.remark));
}
if (rehypePlugins.length > counts.rehype) {
target.options.rehypePlugins.push(...rehypePlugins.slice(counts.rehype));
}
// `remarkRehype` is an object, so Object.assign is idempotent for unchanged keys
// and absorbs any new keys integrations add.
Object.assign(target.options.remarkRehype, remarkRehype);
migratedLegacyPluginCounts.set(target.options, {
remark: remarkPlugins.length,
rehype: rehypePlugins.length,
});
if (!didWarnAboutLegacyMarkdownPlugins) {
didWarnAboutLegacyMarkdownPlugins = true;
console.warn(
'[astro] `markdown.remarkPlugins`, `markdown.rehypePlugins`, and `markdown.remarkRehype` are deprecated. Pass them to `unified({...})` from `@astrojs/markdown-remark` directly instead.',
);
}
} else if (!didWarnAboutProcessorMismatch) {
// Third-party processors can't run remark/rehype plugins. And if they can, they should be passed directly to the processor (like it is for unified) instead of the legacy keys, so we warn either way.
didWarnAboutProcessorMismatch = true;
console.warn(
`[astro] \`markdown.remarkPlugins\`/\`rehypePlugins\`/\`remarkRehype\` are set, but your ` +
`\`${current.name}\` processor doesn't run them. Move them to \`unified({...})\` from ` +
'`@astrojs/markdown-remark` and set `markdown.processor: unified({...})` if you want ' +
'them to apply.',
);
}
}
/**
* Used twice:
* - To validate the user configView on GitHub (pinned to 52e6c34790)
Solutions
- Replace the three keys with markdown: { processor: unified({ remarkPlugins: [...], rehypePlugins: [...], remarkRehype: {...} }) }
- Update third-party integrations that still write to the legacy keys
- Optionally leave them temporarily — behavior is preserved until the keys are removed in a future major
Example fix
// before
export default defineConfig({
markdown: {
remarkPlugins: [remarkToc],
rehypePlugins: [rehypeSlug],
remarkRehype: { clobberPrefix: 'user-content-' },
},
});
// after
import { unified } from '@astrojs/markdown-remark';
export default defineConfig({
markdown: {
processor: unified({
remarkPlugins: [remarkToc],
rehypePlugins: [rehypeSlug],
remarkRehype: { clobberPrefix: 'user-content-' },
}),
},
}); Defensive patterns
Strategy: validation
Validate before calling
// fail CI when legacy markdown plugin keys are set
const legacy = ['remarkPlugins', 'rehypePlugins', 'remarkRehype'];
const present = legacy.filter((k) => config.markdown?.[k] !== undefined);
if (present.length) throw new Error(`Move to processor config: ${present.join(', ')}`); Prevention
- Pass remark/rehype plugins to unified({...}) directly from the start
- Audit integrations that inject markdown plugins after upgrading Astro
- Run a rendered-output snapshot test after migrating plugin config
When it happens
Trigger: The config (or an integration via updateConfig) sets any of markdown.remarkPlugins / markdown.rehypePlugins / markdown.remarkRehype while using the default unified processor; new integrations injecting plugins through the legacy keys re-trigger the fold each validate pass.
Common situations: Any pre-upgrade Astro project with remark/rehype plugins; popular integrations (e.g. MDX-related or documentation tooling) that still push into the legacy keys.
Related errors
- ${colors.bold(plugin)} not applied.
- To inherit Markdown plugins in MDX, please use explicit impo
- [astro] ${names} ${isPlural ? 'are' : 'is'} deprecated. Move
- [astro] `markdown.remarkPlugins`/`rehypePlugins`/`remarkRehy
- ${names} on `mdx({...})` ${isPlural ? 'are' : 'is'} deprecat
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/c148c2a68d89c3dc.
Report an issue: GitHub.