Files
985394417f Fix styled-jsx race condition: styles lost due to concurrent rendering (#92459)
### What?

Fix a race condition in the Pages Router SSR path where styled-jsx
styles were dropped from the rendered HTML.

### Why?

`styledJsxInsertedHTML()` reads and flushes the styled-jsx style
registry. Previously it was called concurrently with the page render via
`Promise.all`:

```js
const [rawStyledJsxInsertedHTML, content] = await Promise.all([
  renderToString(styledJsxInsertedHTML()),
  (async () => { /* render the page */ })(),
])
```

Because both ran at the same time, `styledJsxInsertedHTML()` could (and
in practice did) execute and flush the registry **before** the page
render had finished populating it. The result was that dynamic
styled-jsx styles — those with interpolated expressions that compute
their class names at runtime via DJB2 hashing — were silently dropped
from the SSR output, causing a flash of unstyled content on first load.

This is particularly visible in production deployments where all
components use dynamic styled-jsx (numeric `jsx-*` class names), since
those styles only exist in the registry after rendering completes.

### How?

Serialize the two operations: render the page first, then call
`styledJsxInsertedHTML()`. Since the registry is fully populated by the
time it is read, all styles are captured correctly.

A new e2e test (`test/e2e/styled-jsx-dynamic`) exercises this scenario
with multiple nested components that all use dynamic styled-jsx with
interpolated props, covering the exact FOUC pattern seen in production.

<!-- NEXT_JS_LLM_PR -->

Co-authored-by: Tobias Koppers <[email protected]>
Co-authored-by: Claude <[email protected]>
2026-04-07 17:02:37 +02:00

29 lines
556 B
JavaScript

import DynamicStyled from '../components/DynamicStyled'
import Header from '../components/Header'
import Footer from '../components/Footer'
export default function Page({ mainColor }) {
return (
<div>
<style jsx>{`
div {
color: ${mainColor};
}
`}</style>
<Header bg="navy" fg="white" />
<main>
<DynamicStyled color="blue" />
</main>
<Footer color="purple" />
</div>
)
}
export function getServerSideProps() {
return {
props: {
mainColor: 'green',
},
}
}