diff --git a/.changeset/ninety-boats-fail.md b/.changeset/ninety-boats-fail.md new file mode 100644 index 00000000000..8a2f369eece --- /dev/null +++ b/.changeset/ninety-boats-fail.md @@ -0,0 +1,11 @@ +--- +"@remix-run/dev": patch +--- + +fix(vite): deduplicate `@remix-run/react` + +Pre-bundle Remix dependencies to avoid Remix router duplicates. +Our remix-remix-react-proxy plugin does not process default client and +server entry files since those come from within `node_modules`. +That means that before Vite pre-bundles dependencies (e.g. first time dev server is run) +mismatching Remix routers cause `Error: You must render this element inside a element`. diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 1c3ff65c029..097d9ba5aef 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -429,13 +429,20 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { experimental: { hmrPartialAccept: true }, optimizeDeps: { include: [ - // pre-bundle React dependencies to avoid React duplicates, - // even if React dependencies are not direct dependencies + // Pre-bundle React dependencies to avoid React duplicates, + // even if React dependencies are not direct dependencies. // https://react.dev/warnings/invalid-hook-call-warning#duplicate-react "react", - `react/jsx-runtime`, - `react/jsx-dev-runtime`, + "react/jsx-runtime", + "react/jsx-dev-runtime", "react-dom/client", + + // Pre-bundle Remix dependencies to avoid Remix router duplicates. + // Our remix-remix-react-proxy plugin does not process default client and + // server entry files since those come from within `node_modules`. + // That means that before Vite pre-bundles dependencies (e.g. first time dev server is run) + // mismatching Remix routers cause `Error: You must render this element inside a element`. + "@remix-run/react", ], }, esbuild: { @@ -443,8 +450,14 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { jsxDev: viteCommand !== "build", }, resolve: { - // https://react.dev/warnings/invalid-hook-call-warning#duplicate-react - dedupe: ["react", "react-dom"], + dedupe: [ + // https://react.dev/warnings/invalid-hook-call-warning#duplicate-react + "react", + "react-dom", + + // see description for `@remix-run/react` in `optimizeDeps.include` + "@remix-run/react", + ], }, ...(viteCommand === "build" && { base: pluginConfig.publicPath,