javascriptreactjsreact-routervitestyled-components

React Router Framework - styled components do not work even when SSR is off


I have a React Router Framework project with Vite and I want to use styled components in it, but I can't due to SSR errors. Here is a small example reproducing the error:

app/routes.tsx

import { type RouteConfig, index } from "@react-router/dev/routes";

export default [index("routes/home.tsx")] satisfies RouteConfig;

app/routes/home.tsx

import type { Route } from "./+types/home";
import styled from "styled-components";

export function meta({}: Route.MetaArgs) {
  return [
    { title: "New React Router App" },
    { name: "description", content: "Welcome to React Router!" },
  ];
}

const Text = ({className}: {className?: string}) => <div><p className={className}>MY TEXT</p></div>
const StyledText = styled(Text)`
  color: red;
`

export default function Home() {
  return <main><StyledText /></main>
}

Running this example yields the following error:

[vite] Internal server error: __vite_ssr_import_2__.default is not a function
      at eval (*project-root*/app/routes/home.tsx:34:49)
      at instantiateModule (file:///*project-root*/node_modules/vite/dist/node/chunks/dep-CHZK6zbr.js:52974:5)

It is true that styled components require special configuration to work with server side rendering, but in this case SSR is off:

react-router.config.ts

import type { Config } from "@react-router/dev/config";

export default {
  ssr: false,
} satisfies Config;

vite.config.ts

import { reactRouter } from "@react-router/dev/vite";
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
  build: {
    cssMinify: true,
    ssr: false,
}});

I don't understand why SSR is still tried to be performed. I am not planning to use SSR for my project, and I don't want to waste time configuring styled components for SSR.

I also do not want to use React Router Library instead of React Router Framework, as the latter offers other useful features.

What do I do wrong? How can I completely turn off SSR in this case?


Solution

  • I had the same issue and solved it by adding the below config to vite.config.ts.

    ...
    
        ssr: {
          noExternal: ["styled-components"]
        }
    ...
    

    Complete vite.config.ts code:

    import { reactRouter } from "@react-router/dev/vite";
    import tailwindcss from "@tailwindcss/vite";
    import { defineConfig } from "vite";
    import tsconfigPaths from "vite-tsconfig-paths";
    
    export default defineConfig({
      plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
      build: {
        cssMinify: true,
        ssr: false,
      },
      ssr: {
        noExternal: ["styled-components"]
      }
    });
    

    Looks like this is a React Router issue as it is starting in SSR mode even when ssr flag is set to false in config.