next.js: Any with strategy="beforeInteractive" in RootLayout causes hydration errors
Verify canary release
- I verified that the issue exists in the latest Next.js 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
- Navigate to
localhost:3000
- View hydration errors
Describe the Bug
Following the docs for loading a script using the beforeInteractive
strategy within a RootLayout results in hydration errors.
Ex:
import Script from 'next/script'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
<Script
src="https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js"
strategy="beforeInteractive"
/>
</html>
)
}
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
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 27
- Comments: 30 (2 by maintainers)
Commits related to this issue
- fix!: dark theme (via cookies) add actual preferred color theme switch support via cookies ⚠️ This commit introduce several issues directly linked to the App Router's current limitations : 1. prefe... — committed to nweldev/eurocraties by nweldev 10 months ago
- fix!: dark theme (via cookies) add actual preferred color theme switch support via cookies ⚠️ This commit introduce several issues directly linked to the App Router's current limitations : 1. prefe... — committed to nweldev/eurocraties by nweldev 10 months ago
- feat(error-overlay): handle script under html hydration error (#63403) script tag cannot be placed under html directly, users reported a case in #51242 that having `<Script>` under html will cause h... — committed to vercel/next.js by huozhi 3 months ago
- docs: fix next/script example causing hydration errors (#63401) Related #51242 React will error `In HTML, <script> cannot be a child of <html>. This will cause a hydration error.` when `script` ... — committed to vercel/next.js by huozhi 3 months ago
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?
@altano Stop. To be clear I only edited my message to remove mildly frustrated language. Let’s not turn this into something it’s not.
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.
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
First of all, make your Script component empty closing
<Script src="https://yourURL.to/somewhere/script.is.js" strategy="beforeInteractive"></Script>
Place it in root layout note: async and usual functional component worked - right after
<body>
or - right before</body>
Both of them worked for meThis also eliminated two issues for me:
Result Bunch of stuff gets pushed into the
<head>
but with this way around your<head>
you should end up having two more tags:<link rel="preload" as="script" href="https://yourURL.to/somewhere/script.is.js">
- comes higher in the<head>
<script src="https://yourURL.to/somewhere/script.is.js"></script>
- comes after the<link>
aboveCould someone please confirm?
There is one more related issue - ESLint is complaining about
beforeInteractive
being used outside ofpages/_document.js
(doh)Had to suppress this false positive.
Putting
Script
in thehead
orbody
are the way to go, I filed two PRs to improve this: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.
Adding the
<Script>
withstrategy="beforeInteractive"
insidebody
orhead
it’s creating hydrations errors, even following @deverin guidelines.Next 13.5.4
– Edit – Adding right after
<body>
tag worked for me. Not woking any other place.Perfect, sounds like we’re in total agreement!
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.
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!).
Did you use open and closing component tags? Like this:
<Script></Script>
not self closing
<Script/>
I have hydration issue when I use self-closing tag
I am on Next.js 13.4.9
Could you confirm please 😃
Still here…
Yes @salikn, you can add more native
<script>
s withdangerouslySetInnerHTML
:Also encountering this issue, and disabling edge runtime isn’t an option I have. Has anyone discovered any workarounds for this?
@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.
Tried doing that and the script disappeared… If I don’t use the <head> the script goes to the body (and I need the script at the head). Did you solve 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
beforeInteractive
scripts anywhere into_document.tsx
with the good old page router.@zhangxinyong12’s workaround (of putting the
<Script>
into the<head>
element) seems to work, though.