Skip to content

Audit Pages Router SSR for styled-jsx race condition (concurrent rendering drops dynamic styles) #792

@github-actions

Description

@github-actions

Upstream change

Next.js fixed a race condition in Pages Router SSR where dynamic styled-jsx styles were silently dropped from rendered HTML.

Commit: 9853944 — "Fix styled-jsx race condition: styles lost due to concurrent rendering (#92459)"

What changed

In packages/next/src/server/render.tsx, styledJsxInsertedHTML() was previously called concurrently with the page render via Promise.all:

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

Because both ran at the same time, styledJsxInsertedHTML() could flush the styled-jsx registry before the page render had finished populating it. Dynamic styled-jsx styles (those with interpolated expressions that compute class names at runtime via DJB2 hashing) were silently dropped from SSR output, causing a flash of unstyled content.

Fix: Serialize the operations — render the page first, then call styledJsxInsertedHTML().

Relevance to vinext

vinext reimplements Pages Router SSR in server/dev-server.ts and server/prod-server.ts. If vinext's SSR render path for Pages Router apps also reads the styled-jsx registry concurrently with (or before) page rendering completes, the same race condition could cause dynamic styled-jsx styles to be missing from SSR output.

Action items:

  1. Check whether vinext's Pages Router SSR path calls styledJsxInsertedHTML() or reads the styled-jsx registry
  2. If it does, verify the registry is read after page rendering completes (not concurrently)
  3. If the pattern exists, fix it and add a test with dynamic styled-jsx (interpolated expressions) to verify styles are present in SSR output

Metadata

Metadata

Assignees

No one assigned

    Labels

    nextjs-trackingTracking issue for a Next.js canary change relevant to vinext

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions