-
Notifications
You must be signed in to change notification settings - Fork 27k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Any <Script /> with strategy="beforeInteractive" in RootLayout causes hydration errors #51242
Comments
I am having this issue as well - any updates? @ethanfann Did you find a solution? |
I had the same problem. Have you solved it? |
Having the same issues. I was also expecting this to work as shown in the original issue, based on the documentation and the fact that you could insert @zhangxinyong12's workaround (of putting the |
There is one more related issue - ESLint is complaining about
Had to suppress this false positive.
|
Tried doing that and the script disappeared... If I don't use the the script goes to the body (and I need the script at the head). Did you solve it? |
@JonatasCopernico Can update here too if you manage to get it work in head with the AppRouter because I'm also searching this for a while but didn't manage to get it works. |
@ethanfann Does it make any difference if you place the What I'm suggesting to is to change the top example to this:
|
I have the same problem. I'm doing it exactly as described in the documentation here and getting hydration errors (and a linter warning). I feel like the docs should be updated to reflect the way it's supposed to be done? |
add actual preferred color theme switch support via cookies⚠️ This commit introduce several issues directly linked to the App Router's current limitations : 1. preferred-color-scheme isn't supported anymore 2. every route is now dynamically rendered by default as we use cookies in the root layout A better approach would be to load a client script as "beforeInteractive" to (1) check if a "color-theme" preferrence has been set in the local storage (2) if not, set it based on preferred-color-scheme and (3) add or remove the 'dark' class on document.documentElement accordingly. Then, the DarkModToggle element could work exactly as it is, but using the local storage instead of a cookie. Unfortunately, this wouldn't be a better approach at the moment as the Next.js Script component isn't supported by the App Router. see vercel/next.js#51242 and https://nextjs.org/docs/app/api-reference/functions/cookies and https://nextjs.org/docs/pages/api-reference/components/script#beforeinteractive inspired by https://michaelangelo.io/blog/darkmode-rsc
add actual preferred color theme switch support via cookies⚠️ This commit introduce several issues directly linked to the App Router's current limitations : 1. preferred-color-scheme isn't supported anymore 2. every route is now dynamically rendered by default as we use cookies in the root layout A better approach would be to load a client script as "beforeInteractive" to (1) check if a "color-theme" preferrence has been set in the local storage (2) if not, set it based on preferred-color-scheme and (3) add or remove the 'dark' class on document.documentElement accordingly. Then, the DarkModToggle element could work exactly as it is, but using the local storage instead of a cookie. Unfortunately, this wouldn't be a better approach at the moment as the Next.js Script component isn't supported by the App Router. see vercel/next.js#51242 and https://nextjs.org/docs/app/api-reference/functions/cookies and https://nextjs.org/docs/pages/api-reference/components/script#beforeinteractive inspired by https://michaelangelo.io/blog/darkmode-rsc
Still here... |
UPDATE 23/09: Don't use edge runtime if you want this to work Hello Everyone After fiddling around with this next/script component after reading your inputs, I manged to find a working solution. I need someone to confirm it. I am on nextjs 13.4.19 Try this
This also eliminated two issues for me:
Result
Could someone please confirm? |
Adding the
Next 13.5.4 -- Edit -- |
Did you use open and closing component tags? Like this:
not self closing
I have hydration issue when I use self-closing tagI am on Next.js 13.4.9 Could you confirm please :) |
Even with deverin's setup (including <Script></Script>) Im still getting the hydration errors. |
This bug was giving me a real headache (I had an external script which is a wasm polyfill that was indeterministically present/not present depending on load speeds) until @deverin workaround. It works for me now (using all his mentioned steps!). |
If placed in Warning: Prop `dangerouslySetInnerHTML` did not match. Server: "" Client: "(self.__next_s=self.__next_s||[]).push([0,{\"children\":\"\\n window.dataLayer = window.dataLayer || [];\\n function gtag(){dataLayer.push(arguments);}\\n gtag('consent','default',{\\n 'ad_storage':'denied',\\n 'analytics_storage':'denied',\\n 'wait_for_update': 500\\n });\\n gtag('set', 'ads_data_redaction', true);\\n \"}])"
at script
at Script (webpack-internal:///(app-pages-browser)/../../node_modules/next/dist/client/script.js:175:13)
at head
at html And the other common warning with this issue -
|
I found even using next/script with strategy="beforeInteractive" right inside the body tag, the scripts are getting executed before next and application code, actually they are injected after the initial assets. This makes polyfills not working. |
I'm getting this as well. Even doing the above workaround still gives me several errors. @leerob any chance you could let us know what's happening with this? It's hard to convince my team that transitioning to next is a good idea when on render in dev you get several unavoidable errors right away. |
Thank you for editing your message. Let’s all remember that this is a free, open source framework and we’re all on the line for fixing things. We are not entitled to a fix from Vercel. |
@altano Stop.
Cmon man, are you serious? I'm not saying we're entitled to a fix. Vercel is a company that makes profit (~60 million?) by getting people to use their framework and deploy that on their infrastructure. They've provided no update on this issue. Of course I'm frustrated when I'm seeing an issue like this that hasn't gotten any response in 6 months. If my statement is unhelpful then you coming in here and adding a nothing burger comment like that is even more so. |
Perfect, sounds like we're in total agreement! |
Just wanted to pop in here with my experience. I needed to add a cookie consent manager as a The script tag is in the head, but hydration still fails and Next.js switches to client-side rendering. Hopefully they're able to provide better support for Quick note about @jaapaurelio's approach: This populated the script in the body for me, which would not fit the behavior I needed from EDIT: I previously said this worked without issues, but I was mistaken. My console errors were being minified, which I didn't realize was the hydration error in production. |
Also encountering this issue, and disabling edge runtime isn't an option I have. Has anyone discovered any workarounds for this? |
I'am trying to implement the CookiePro by OneTrust script. The script needs to be inside the I have followed the official docs: https://nextjs.org/docs/app/api-reference/components/script#beforeinteractive Inside my export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="hu">
<body>{children}</body>
{/* eslint-disable-next-line @next/next/no-before-interactive-script-outside-document,react/self-closing-comp */}
<Script
src="https://cookie-cdn.cookiepro.com/scripttemplates/otSDKStub.js"
charSet="UTF-8"
data-document-language="true"
data-domain-script="XXXX"
async
strategy="beforeInteractive"
></Script>
</html>
);
} And I'am getting this error:
I have tried to follow deverin, but with no luck. Next.js version 13.5.6 |
any luck solving this problem? I'm trying to add OneTrust through beforeinteractive and i'm heaving the same error. |
My solution: put it directly inside the native I know it's the opposite as the docs says/recommends, but it was the only solution that worked for me. layout.tsx export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="hu">
<head>
<CookiePro />
</head>
<body>{children}</body>
</html>
);
} cookiepro.tsx export function CookiePro() {
return (
<>
<script
src="https://cookie-cdn.cookiepro.com/scripttemplates/otSDKStub.js"
charSet="UTF-8"
data-document-language="true"
data-domain-script="XXXX"
async
></script>
<script
dangerouslySetInnerHTML={{
__html: `
...
`,
}}
></script>
</>
);
} |
Thanks @borzaka Yes this one actually work, |
Yes @salikn, you can add more native <script
dangerouslySetInnerHTML={{
__html: `
...
`,
}}
></script> |
Putting
|
script tag cannot be placed under html directly, users reported a case in #51242 that having `<Script>` under html will cause hydration error, this will display the React hydration error related warning of bad usage for it. You will see this warning in dev overlay instead of displaying nothing ``` In HTML, <script> cannot be a child of <html>. This will cause a hydration error. ``` Added two other react warnings detection patterns as well * `Warning: In HTML, text nodes cannot be a child of <%s>.\nThis will cause a hydration error.',` * `Warning: In HTML, whitespace text nodes cann...` But tested they're not generating hydration errors, only warnings in console, so we don't need to have tests for them. Closes NEXT-2835
Related #51242 React will error `In HTML, <script> cannot be a child of <html>. This will cause a hydration error.` when `script` is rendered under `html` directly. The examples in our docs are causing this hydration error. Moving it under `body` tag will fix the hydration error Closes NEXT-2834 Co-authored-by: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com>
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Verify canary release
Provide environment information
Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 22.5.0: Mon Apr 24 20:52:24 PDT 2023; root:xnu-8796.121.2~5/RELEASE_ARM64_T6000 Binaries: Node: 18.16.0 npm: 9.5.1 Yarn: N/A pnpm: N/A Relevant packages: next: 13.4.6-canary.0 eslint-config-next: N/A react: 18.2.0 react-dom: 18.2.0 typescript: N/A
Which area(s) of Next.js are affected? (leave empty if unsure)
App directory (appDir: true), Script optimization (next/script)
Link to the code that reproduces this issue or a replay of the bug
https://github.com/ethanfann/beforeInteractive-script-rootLayout-hydration-errors
To Reproduce
git clone https://github.com/ethanfann/beforeInteractive-script-rootLayout-hydration-errors
cd beforeInteractive-script-rootLayout-hydration-errors
npm install
npm run dev
localhost:3000
Describe the Bug
Following the docs for loading a script using the
beforeInteractive
strategy within a RootLayout results in hydration errors.Ex:
Expected Behavior
No hydration errors should occur with barebones example sites that follow official documentation.
Which browser are you using? (if relevant)
Chrome 114.0.5735.106 (Official Build) (arm64)
How are you deploying your application? (if relevant)
No response
The text was updated successfully, but these errors were encountered: