A `<noscript>` with an element inside fails hydration and replaces the server DOM

Ouverte
#141 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
48/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
next.js, react, typescript
Domaine
frontend

Piste de recherche

Start with the reproduction in app/noscript/page.jsx and compare production behavior with and without withRedact using the reported Next.js and React versions. Check related issue #43, whose unmerged change may cover this case and conflicts with main. Done means the noscript example hydrates without a page error and keeps the server-rendered DOM.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Version: @tanstack/redact 0.2.6 via withRedact, Next.js 16.4.3 (App Router, Turbopack, production), react/react-dom 19.3.1, Chromium.

What happens

A <noscript> that contains an element, such as Google Tag Manager's <noscript><iframe …></noscript>, makes Redact report Hydration mismatch. and replace the server-rendered DOM. React 19.3.1 hydrates the same page with no errors and keeps the server nodes.

Repro

// app/noscript/page.jsx
export default function Page() {
  return (
    <main>
      <p id="content">Page content</p>
      <noscript>
        <iframe src="about:blank" height="0" width="0" style={{ display: 'none' }} title="No script" />
      </noscript>
    </main>
  )
}

next build && next start, then load /noscript, with and without withRedact:

React 19.3.1 Redact 0.2.6
Server <p id="content"> kept yes no, replaced
pageerror none Hydration mismatch.

Impact

GTM's snippet sits at the end of the root layout's <body>, so every page fails hydration and the whole document is rebuilt, including the <head> (about 120 elements in our app).

Where

With scripting enabled, the browser parses a <noscript>'s content as text, so the server's <iframe> never exists as an element. React treats noscript as a text-content element and doesn't hydrate its children. Redact appears to hydrate them as elements and finds only text.

Passing the same content as markup hydrates cleanly, and works as a workaround for now:

<noscript dangerouslySetInnerHTML={{ __html: '<iframe src="…" height="0" width="0" style="display:none" title="…"></iframe>' }} />

Related: #43 includes a change that keeps <noscript> content opaque during hydration, which may cover this. It hasn't landed yet and currently conflicts with main.

Langage dominant
TypeScript
Étoiles
537
Forks
22
Merge moyen
11 h 28 min
PR mergées (30 j)
34

Préparer son environnement

Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de TanStack/redact

Toutes les issues de TanStack/redact

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.