Describe the bug
A top-level fragment containing a client-only component followed by a route subtree that suspends produces a hydration mismatch. The initial server render completes, but client hydration cannot find the route's DOM node and the app is replaced by the error boundary.
This is reduced from SolidStart issue solidjs/solid-start#1452. It uses the built-in clientOnly helper plus a plain createResource; TanStack Query is not involved.
const ClientComponent = clientOnly(() => import("./ClientComponent"));
export default function App() {
return (
<>
<ClientComponent />
<Router root={props => <Suspense>{props.children}</Suspense>}>
<FileRoutes />
</Router>
</>
);
}
The matching route suspends for one second:
export default function Home() {
const [data] = createResource(async () => {
await new Promise(resolve => setTimeout(resolve, 1000));
return "loaded";
});
return <p>{data()}</p>;
}
Reproduction
https://github.com/birkskyum/repro-solid-client-only-suspense-hydration
git clone https://github.com/birkskyum/repro-solid-client-only-suspense-hydration.git
cd repro-solid-client-only-suspense-hydration
pnpm install
pnpm dev
Open http://localhost:4175 and check the browser console.
Actual behavior
Hydration throws and the app is cleared:
Error: Hydration Mismatch. Unable to find DOM nodes for hydration key: 000000110000000001
<p></p>
at getNextElement (.../solid-js/web/dist/dev.js)
at Home (src/routes/index.tsx)
Expected behavior
The client-only component should mount, and the route should display loaded after the resource resolves, without a hydration error.
Controls
Both of these prevent the mismatch:
- Replace the top-level fragment in
src/app.tsx with a real <div> wrapper.
- Make the route synchronous instead of reading the suspending resource.
Disabling the SolidStart dev overlay does not change the result; it is disabled in the reproduction.
Versions
solid-js@1.9.15
@solidjs/start@2.0.0
@solidjs/router@1.0.0
vite@8.2.1
Downstream report: solidjs/solid-start#1452
In that report this was identified as another variation of the top-level fragment hydration bug, similar to portals: solidjs/solid-start#1452 (comment)
Describe the bug
A top-level fragment containing a client-only component followed by a route subtree that suspends produces a hydration mismatch. The initial server render completes, but client hydration cannot find the route's DOM node and the app is replaced by the error boundary.
This is reduced from SolidStart issue solidjs/solid-start#1452. It uses the built-in
clientOnlyhelper plus a plaincreateResource; TanStack Query is not involved.The matching route suspends for one second:
Reproduction
https://github.com/birkskyum/repro-solid-client-only-suspense-hydration
git clone https://github.com/birkskyum/repro-solid-client-only-suspense-hydration.git cd repro-solid-client-only-suspense-hydration pnpm install pnpm devOpen http://localhost:4175 and check the browser console.
Actual behavior
Hydration throws and the app is cleared:
Expected behavior
The client-only component should mount, and the route should display
loadedafter the resource resolves, without a hydration error.Controls
Both of these prevent the mismatch:
src/app.tsxwith a real<div>wrapper.Disabling the SolidStart dev overlay does not change the result; it is disabled in the reproduction.
Versions
solid-js@1.9.15@solidjs/start@2.0.0@solidjs/router@1.0.0vite@8.2.1Downstream report: solidjs/solid-start#1452
In that report this was identified as another variation of the top-level fragment hydration bug, similar to portals: solidjs/solid-start#1452 (comment)