fix: broaden captureExistingTree to find React root in Next.js App Router
Next.js 13+ App Router calls hydrateRoot on <html> or <body> directly
(not on a #__next div), so __reactFiber$ annotations land on
document.documentElement or document.body.
Changes:
- Add document.documentElement to the candidate list (covers App Router)
- Extract getFiber() helper to remove repeated key-scan loop
- Add DOM-wide fallback scan (querySelectorAll('*')) so any React app
is found regardless of its root container convention
- Remove the early !tree bail-out — post FIBER_TREE_UPDATE even with a
sparse tree, matching onCommitFiberRoot's behaviour
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
8bbee987ff
commit
f707ecd7b3
@@ -923,28 +923,44 @@ export function buildProxyFiberHookScript(): string {
|
|||||||
// Attempt 2 (2 s delay) – hook ran before hydration or Suspense deferred.
|
// Attempt 2 (2 s delay) – hook ran before hydration or Suspense deferred.
|
||||||
function captureExistingTree() {
|
function captureExistingTree() {
|
||||||
// Find any DOM element that React has annotated with a fiber reference.
|
// Find any DOM element that React has annotated with a fiber reference.
|
||||||
|
// Priority order covers the most common React root containers:
|
||||||
|
// - Next.js Pages Router: #__next
|
||||||
|
// - CRA / Vite: #root
|
||||||
|
// - Generic: #app
|
||||||
|
// - Next.js App Router: <html> or <body> (hydrateRoot on document)
|
||||||
|
// - Fallback DOM scan: first annotated element anywhere in <body>
|
||||||
var candidates = [
|
var candidates = [
|
||||||
document.getElementById('__next'),
|
document.getElementById('__next'),
|
||||||
document.getElementById('root'),
|
document.getElementById('root'),
|
||||||
document.getElementById('app'),
|
document.getElementById('app'),
|
||||||
|
document.documentElement, // <html> — App Router hydrateRoot target
|
||||||
document.body,
|
document.body,
|
||||||
];
|
];
|
||||||
|
|
||||||
var fiber = null;
|
function getFiber(el) {
|
||||||
for (var ci = 0; ci < candidates.length; ci++) {
|
if (!el) return null;
|
||||||
var el = candidates[ci];
|
|
||||||
if (!el) continue;
|
|
||||||
var keys = Object.keys(el);
|
var keys = Object.keys(el);
|
||||||
for (var ki = 0; ki < keys.length; ki++) {
|
for (var ki = 0; ki < keys.length; ki++) {
|
||||||
if (keys[ki].indexOf('__reactFiber$') === 0) {
|
if (keys[ki].indexOf('__reactFiber$') === 0) return el[keys[ki]];
|
||||||
fiber = el[keys[ki]];
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fiber = null;
|
||||||
|
for (var ci = 0; ci < candidates.length; ci++) {
|
||||||
|
fiber = getFiber(candidates[ci]);
|
||||||
if (fiber) break;
|
if (fiber) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fiber) return; // React not yet mounted on any known container.
|
// Last resort: walk the DOM looking for any annotated element.
|
||||||
|
if (!fiber) {
|
||||||
|
var allEls = document.body ? document.body.querySelectorAll('*') : [];
|
||||||
|
for (var di = 0; di < allEls.length && !fiber; di++) {
|
||||||
|
fiber = getFiber(allEls[di]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fiber) return; // React not yet mounted anywhere in the document.
|
||||||
|
|
||||||
// Walk up to the HostRoot (the sentinel fiber React builds the tree from).
|
// Walk up to the HostRoot (the sentinel fiber React builds the tree from).
|
||||||
var f = fiber;
|
var f = fiber;
|
||||||
@@ -954,8 +970,6 @@ export function buildProxyFiberHookScript(): string {
|
|||||||
nodeMap = {};
|
nodeMap = {};
|
||||||
fiberMap = new WeakMap();
|
fiberMap = new WeakMap();
|
||||||
var tree = serializeFiber(f, '');
|
var tree = serializeFiber(f, '');
|
||||||
if (!tree) return; // Nothing serializable yet.
|
|
||||||
|
|
||||||
reapplyOverrides();
|
reapplyOverrides();
|
||||||
post({ type: 'FIBER_TREE_UPDATE', root: tree });
|
post({ type: 'FIBER_TREE_UPDATE', root: tree });
|
||||||
if (selectedNodeId) updateHighlight();
|
if (selectedNodeId) updateHighlight();
|
||||||
|
|||||||
Reference in New Issue
Block a user