Skip to content

Problems with nonce #162

@R1ON

Description

@R1ON

I'm encountering a hydration error when passing nonce to PublicEnvScript. Do you have any ideas on how to fix this?

"next-runtime-env": "^3.2.2",
"next": "15.1.7",
"react": "19.0.0",

middleware.ts

export const middleware = (request: NextRequest) => {
  const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
  requestHeaders.set('x-nonce', nonce);
  requestHeaders.set(
      'Content-Security-Policy',
      contentSecurityPolicyHeaderValue,
   );

  const response = NextResponse.next({
      request: {
        headers: requestHeaders,
      },
    });

    response.headers.set(
      'Content-Security-Policy',
      contentSecurityPolicyHeaderValue,
    );

    return response;
}

app/layout.tsx

export default async function RootLayout({ children }: PropsWithChildren) {
  const headersList = await headers();
  const nonce = headersList.get('x-nonce') || 'unknown-nonce';

   return (
      <html lang="ru">
        <head>
          <PublicEnvScript nonce={nonce} />
       </head>
     </html>
   );
}

Error:

A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:

- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.

It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.

https://react.dev/link/hydration-mismatch

  ...
    <HotReload assetPrefix="">
      <ReactDevOverlay state={{nextId:1, ...}} dispatcher={{...}}>
        <DevRootHTTPAccessFallbackBoundary>
          <HTTPAccessFallbackBoundary notFound={<NotAllowedRootHTTPFallbackError>}>
            <HTTPAccessFallbackErrorBoundary pathname="/" notFound={<NotAllowedRootHTTPFallbackError>} ...>
              <RedirectBoundary>
                <RedirectErrorBoundary router={{...}}>
                  <Head>
                  <RootLayout>
                    <html lang="ru" className="montserrat...">
                      <head>
                        <PublicEnvScript>
                          <EnvScript>
                            <Script strategy="beforeInte..." nonce="ZDVhYzUzZT..." suppressHydrationWarning={true} ...>
                              <script
+                               nonce={undefined}
-                               nonce=""
                                dangerouslySetInnerHTML={{__html:"(self.__ne..."}}
                              >
                      ...
                  ...
        ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions