remix-run / remix

Build Better Websites. Create modern, resilient user experiences with web fundamentals.
https://remix.run
MIT License
29.47k stars 2.48k forks source link

Vite: ErrorBoundary with predefined links cause "Expected server HTML to contain a matching <link> in <head>." #9144

Open mikkpokk opened 6 months ago

mikkpokk commented 6 months ago

Reproduction

  1. Create an empty project npx create-remix@latest --template remix-run/remix/templates/express
  2. Install sass npm install -D sass
  3. Run dev server npm run dev
  4. Create file "Test.module.scss" with contents:
.Test {
    background: red;
    color: white;
}
  1. Create route file routes/test.tsx:
import type { MetaFunction } from "@remix-run/node";
import {Link} from '@remix-run/react'

export const meta: MetaFunction = () => {
    return [
        { title: "Test" },
        { name: "description", content: "Welcome to Remix!" },
    ];
};

export default function Index() {
    console.log(test.dagta) // <- this is necessary to demonstrate ErrorBoundary

    return (
        <div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
            <h1>Welcome to Remix</h1>
            <ul>
                <li>
                    <Link to={'/'}>Index</Link>
                </li>
                <li>
                    <Link to={'/test'}>Test</Link>
                </li>
            </ul>
        </div>
    );
}

export const ErrorBoundary = () => {
    return (
        <div>
            Test
        </div>
    )
}
  1. Replace index route file routes/_index.tsx
import type { MetaFunction } from "@remix-run/node";
import {Link} from '@remix-run/react'

export const meta: MetaFunction = () => {
  return [
    { title: "New Remix App" },
    { name: "description", content: "Welcome to Remix!" },
  ];
};

export default function Index() {
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
      <h1>Welcome to Remix</h1>
      <ul>
        <li>
          <Link to={'/'}>Index</Link>
        </li>
        <li>
          <Link to={'/test'}>Test</Link>
        </li>
      </ul>
    </div>
  );
}
  1. Replace root file contents root.tsx: Applying styles from sass, plus adding custom links
import {
    Links,
    Meta,
    Outlet,
    Scripts,
    ScrollRestoration,
} from '@remix-run/react'
import {LinksFunction} from '@remix-run/node'
import style from './Test.module.scss'

export const links: LinksFunction = () => [
    {rel: 'preconnect', href: 'https://github.com'},
    {rel: 'dns-prefetch', href: 'https://github.com'},
]

export function Layout({children}: { children: React.ReactNode }) {
    return (
        <html lang="en">
        <head>
            <meta charSet="utf-8"/>
            <meta name="viewport" content="width=device-width, initial-scale=1"/>
            <Meta/>
            <Links/>
        </head>
        <body>
            <div className={style.Test}>HEADER</div>
            {children}
            <ScrollRestoration/>
            <Scripts/>
        </body>
        </html>
    )
}

export default function App() {
    return <Outlet/>
}

System Info

System:
    OS: macOS 14.2.1
    CPU: (16) arm64 Apple M3 Max
    Memory: 117.86 MB / 48.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 21.7.1 - /opt/homebrew/bin/node
    npm: 10.5.0 - /opt/homebrew/bin/npm
  Browsers:
    Chrome: 123.0.6312.86
    Safari: 17.2.1
  npmPackages:
    @remix-run/css-bundle: ^2.8.1 => 2.8.1 
    @remix-run/dev: ^2.8.1 => 2.8.1 
    @remix-run/eslint-config: ^2.8.1 => 2.8.1 
    @remix-run/node: ^2.8.1 => 2.8.1 
    @remix-run/react: ^2.8.1 => 2.8.1 
    @remix-run/serve: ^2.8.1 => 2.8.1 
    vite: ^5.1.0 => 5.2.6

Used Package Manager

npm

Expected Behavior

When hard-reloading /test route, it should return ErrorBoundary without breaking styles.

Actual Behavior

All the styles will be removed during the mount due to "Expected server HTML to contain a matching in ."

Anomaly is not happening when using the Link navigation or production mode. It only occurrs during the inital load and dev server.

mizi-lin commented 3 months ago

me too

janukkeb commented 2 months ago

same

didiercapozzi commented 3 days ago

same