Skip to content

suppress React 19 script warning by not rendering ThemeScript on client - #386

Open
jakubwarkusz wants to merge 1 commit into
pacocoursey:mainfrom
jakubwarkusz:fix/react-19-script-warning
Open

suppress React 19 script warning by not rendering ThemeScript on client#386
jakubwarkusz wants to merge 1 commit into
pacocoursey:mainfrom
jakubwarkusz:fix/react-19-script-warning

Conversation

@jakubwarkusz

Copy link
Copy Markdown

Problem

Since Next.js 16.2 ThemeProvider triggers a browser warning:

Encountered a script tag while rendering React component. Scripts inside React components are never executed when rendering on the client. Consider using template tag instead

Reported in #385.

Fix

Return null from ThemeScript when running on the client
(typeof window !== 'undefined'). The script only needs to be present in the
SSR-generated HTML where the browser executes it once before hydration. After
that it is no longer needed.

The existing nonce prop, which was already gated behind
typeof window === 'undefined', is simplified accordingly.

@jakubwarkusz

Copy link
Copy Markdown
Author

This is also fixed by my own library themes.wrksz.dev that's a near drop-in replacement for next-themes. See this

hifizz added a commit to hifizz/thread-chatbot that referenced this pull request Aug 24, 2026
React 19.2 warns because next-themes 0.4.6 renders its bootstrap script again on the client, where React-created script elements do not execute.\n\nPatch both CJS and ESM builds so ThemeScript remains in SSR output but returns null on the client. This follows upstream pacocoursey/next-themes#386 while pacocoursey/next-themes#385 remains open and no fixed release is available.\n\nRemove the patch after upgrading to an upstream release that contains the fix.
@bolechen

Copy link
Copy Markdown

+1 — we ran into the same Encountered a script tag while rendering React component. Scripts inside React components are never executed warning on React 19 / Next.js 16.2, most reliably on localized 404 renders where ThemeProvider re-mounts and ThemeScript ends up running on the client.

We shipped an equivalent fix via pnpm patch — adding if (typeof window !== 'undefined') return null at the top of ThemeScript, leaving the SSR path untouched so the FOUC-prevention script is still injected — and added e2e coverage across locales × light/dark/system on direct 404 visits plus client-side navigation, asserting no script warning and correct theme init. All green, no regression, warning gone.

This looks like the correct minimal fix. Is there anything blocking a merge here? CI is passing — happy to help if a rebase or test additions would help it land.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants