remix-run/react-router · error
The "@mdx-js/rollup" plugin should be placed before the…
Error message
The "@mdx-js/rollup" plugin should be placed before the React Router plugin in your Vite config
What it means
React Router's Vite plugin registers a config hook that validates plugin ordering. The '@mdx-js/rollup' plugin must appear BEFORE the React Router plugin in the Vite 'plugins' array so that MDX route modules are compiled to plain JS before React Router applies its own route-module transforms. The check compares the index of '@mdx-js/rollup' against the index of the react-router plugin and throws when MDX comes later, because the React Router transforms would otherwise run on uncompiled .mdx files.
Solutions
- Move mdx() above reactRouter() in the vite.config.ts plugins array
- Re-run 'react-router dev' or 'react-router build' to confirm the config hook passes
- Check for duplicated plugin registrations (e.g. mdx() added twice in different spots) if the error persists
Example fix
// before (vite.config.ts)
import { reactRouter } from "@react-router/dev/vite";
import mdx from "@mdx-js/rollup";
export default defineConfig({
plugins: [reactRouter(), mdx()],
});
// after
export default defineConfig({
plugins: [mdx(), reactRouter()],
}); Defensive patterns
Strategy: validation
Validate before calling
// run before vite boots (e.g. in a prebuild script)
import { resolveConfig } from "vite";
const cfg = await resolveConfig({ configFile: "vite.config.ts" }, "serve");
const names = cfg.plugins.map((p) => p.name);
const mdx = names.indexOf("@mdx-js/rollup");
const rr = names.findIndex((n) => n.startsWith("react-router"));
if (mdx !== -1 && rr !== -1 && mdx > rr) {
throw new Error("Move @mdx-js/rollup before the React Router plugin");
} Prevention
- Order plugins that compile source (mdx, mdsvx, legacy) above framework plugins
- Add a lint/CI step that asserts plugin order in vite.config.ts
- When adding new Vite plugins, insert them relative to reactRouter(), not at the array end
When it happens
Trigger: A vite.config.ts whose plugins array is ordered as [reactRouter(), mdx()], i.e. mdxPluginIndex >= 0 and mdxPluginIndex > reactRouterPluginIndex (where the React Router index matches plugin names 'react-router' or 'react-router/rsc').
Common situations: Adding MDX support to a Framework Mode app by appending mdx() at the end of the plugins array; copying a Vite config from an MDX tutorial that places mdx() last; converting a plain Vite+MDX site to React Router and keeping the old plugin order.
Related errors
- The "@vitejs/plugin-rsc" plugin should be placed after the…
- Could not find package.json in
- Custom Vite manifest paths are not supported
- Error loading
- Failed to load CSS for
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/33b46107e0ec2003.
Report an issue: GitHub.
Appendix: source
Thrown at packages/react-router-dev/vite/plugins/validate-plugin-order.ts:32
let reactRouterRscPluginIndex = pluginIndex("react-router/rsc");
let viteRscPluginIndex = pluginIndex("rsc");
if (
reactRouterRscPluginIndex >= 0 &&
viteRscPluginIndex >= 0 &&
reactRouterRscPluginIndex > viteRscPluginIndex
) {
throw new Error(
`The "@vitejs/plugin-rsc" plugin should be placed after the React Router RSC plugin in your Vite config`,
);
}
let reactRouterPluginIndex = pluginIndex([
"react-router",
"react-router/rsc",
]);
let mdxPluginIndex = pluginIndex("@mdx-js/rollup");
if (mdxPluginIndex >= 0 && mdxPluginIndex > reactRouterPluginIndex) {
throw new Error(
`The "@mdx-js/rollup" plugin should be placed before the React Router plugin in your Vite config`,
);
}
},
};
}
View on GitHub (pinned to 6beaca3952)