remix-run/react-router · error · Error

The "@vitejs/plugin-rsc" plugin should be placed after the R

Error message

The "@vitejs/plugin-rsc" plugin should be placed after the React Router RSC plugin in your Vite config

What it means

Thrown from the configResolved hook of the react-router:validate-plugin-order plugin when both `react-router/rsc` and `@vitejs/plugin-rsc` (plugin name `rsc`) are present in the Vite config and the React Router RSC plugin appears BEFORE @vitejs/plugin-rsc. React Router's RSC plugin must run earlier so that @vitejs/plugin-rsc receives already-processed RSC module graph.

Source

Thrown at packages/react-router-dev/vite/plugins/validate-plugin-order.ts:21

export function validatePluginOrder(): Vite.Plugin {
  return {
    name: "react-router:validate-plugin-order",
    configResolved(viteConfig) {
      let pluginIndex = (pluginName: string | string[]) => {
        pluginName = Array.isArray(pluginName) ? pluginName : [pluginName];
        return viteConfig.plugins.findIndex((plugin) =>
          pluginName.includes(plugin.name),
        );
      };

      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 1fd704a7da)

Solutions

  1. In vite.config.ts, ensure reactRouter() (which contains the react-router/rsc sub-plugin) is listed BEFORE pluginRsc(): `plugins: [reactRouter(), pluginRsc()]`.
  2. After editing, run `pnpm dev` or `pnpm build` to re-trigger configResolved and confirm the error is gone.
  3. Remove any plugin-sorting/flattening helpers in the config that reorder the array.
  4. Verify you are not double-registering plugin-rsc via a preset or framework preset that injects it earlier.

Example fix

// vite.config.ts
// before
import { reactRouter } from '@react-router/dev/vite';
import { rsc } from '@vitejs/plugin-rsc';
export default defineConfig({ plugins: [rsc(), reactRouter()] });
// after
export default defineConfig({ plugins: [reactRouter(), rsc()] });
Defensive patterns

Strategy: validation

Validate before calling

// static check of plugin order before running vite
import { reactRouter } from '@react-router/dev/vite';
import { rsc } from '@vitejs/plugin-rsc';
const plugins = [reactRouter(), rsc()];
const rrIdx = plugins.findIndex((p) => (p.name ?? '').includes('react-router/rsc'));
const rscIdx = plugins.findIndex((p) => (p.name ?? '') === 'rsc');
if (rrIdx >= 0 && rscIdx >= 0 && rrIdx > rscIdx) throw new Error('reactRouter() must come before rsc()');

Type guard

function pluginsOrderedCorrectly(plugins: { name: string }[]): boolean {
  const rr = plugins.findIndex((p) => p.name.includes('react-router/rsc'));
  const rsc = plugins.findIndex((p) => p.name === 'rsc');
  return !(rr >= 0 && rsc >= 0 && rr > rsc);
}

Prevention

When it happens

Trigger: In vite.config.ts the user registers plugins in the order [reactRouter(), rsc()] but somehow the resolved plugin array has `rsc` before `react-router/rsc`. More commonly: the user places @vitejs/plugin-rsc() above reactRouter() in the plugins array, OR plugin aliasing/merging reorders them.

Common situations: Following a tutorial that lists plugin-rsc before react-router. Copy-pasting an RSC example config without preserving order. Wrapping plugins in a helper that flattens/sorts them. Upgrading to RSC Framework Mode from an older sample.

Related errors


AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12). Data as JSON: /api/errors/7ccd9b0d89a230b0. Report an issue: GitHub.