Skip to content

404 / ErrorBoundary triggers hydration mismatch and causes CSS to remount (FOUC) #3319

@michael-land

Description

@michael-land

What is the location of your example repository?

https://github.com/Shopify/hydrogen/tree/main/templates/skeleton

Which package or tool is having this issue?

Hydrogen

What version of that package or tool are you using?

2025.7.0

What version of Remix are you using?

React Router 7.9.6

Steps to Reproduce

CleanShot.2025-11-20.at.10.19.43.mp4

When using Hydrogen (React Router v7 Framework Mode), navigating to a route that triggers ErrorBoundary causes all CSS to re-fetch and re-mount, resulting in a visible flash of unstyled content (FOUC).

This happens even when using the official Hydrogen skeleton template with no custom logic.

Steps to Reproduce

  1. Create a new Hydrogen project from the official skeleton template:

  2. pnpm create @shopify/hydrogen@latest, choose "Skeleton" template

  3. Open the <Header /> component and add a link to a non-existing route:
    <Link to="/not-found">Not Found</Link>

  4. Start the dev server:
    pnpm run dev
    Click the /not-found link → the ErrorBoundary renders.

Observed behavior:

The global stylesheet is fetched again.
CSS is re-mounted.
A brief flash of unstyled content occurs before styles re-apply.

Environment:

    "@shopify/hydrogen": "2025.7.0",
    "@shopify/remix-oxygen": "3.0.1",
    "react-router": "7.9.6",
    "@react-router/dev": "7.9.6"
    "@react-router/fs-routes": "7.9.6",
    "@shopify/cli": "3.87.4",
    "@shopify/mini-oxygen": "4.0.0",
    "@shopify/oxygen-workers-types": "4.2.0",
    "tailwindcss": "4.1.17",
    "vite": "6.3.6",

Expected Behavior

Navigating to an error route should not cause CSS to re-fetch or re-mount. The layout and global styles should remain stable across route transitions, including error boundaries.

Actual Behavior

Each time a route enters ErrorBoundary:

The browser re-downloads the CSS file (root.css or global stylesheet)
The UI flashes without styles briefly

Image Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions