fix(js): HTMLMetaElement.content is read/write (#210) (#211)

`<meta>.content` was a getter-only stub. `next/head` and `next/document`
  iterate <meta> tags and assign `.content` during hydration, which threw
  `Cannot set property content`, React caught and retried in a tight loop,
  the page never mounted, and the error spammed the console thousands of
  times. Traveloka and other Next.js sites doing meta management were unusable.

  Now reflects the content attribute with both get and set, per spec.
  Template's `.content` (DocumentFragment) is unchanged.

  Closes #210.
This commit is contained in:
SGavrl authored and GitHub committed 2026-05-31 11:16:35 +00:00
1 parent 326096e20f
commit 3c3798b197
1 file changed
+17 -3
+17 -3
View File
@@ -515,9 +515,23 @@ class Element extends Node {
return ids.map(_wrapEl).filter(Boolean);
}
get content() {
if (this.localName !== 'template') return undefined;
if (!this._templateContent) this._templateContent = document.createDocumentFragment();
return this._templateContent;
// <template>.content is a DocumentFragment; <meta>.content reflects
// the content attribute (read/write per spec). Next.js' next/head
// iterates <meta> tags and sets .content during hydration, which
// threw with the previous getter-only stub and put React into an
// infinite retry loop (issue #210).
const tag = this.localName;
if (tag === 'template') {
if (!this._templateContent) this._templateContent = document.createDocumentFragment();
return this._templateContent;
}
if (tag === 'meta') return this.getAttribute('content') || '';
return undefined;
}
set content(v) {
if (this.localName === 'meta') {
this.setAttribute('content', v == null ? '' : String(v));
}
}
get childElementCount() { return this.children.length; }
get firstElementChild() { return this.children[0] || null; }