facebook/react · error · Error
257
257
Error message
Portals are not currently supported by the server renderer. Render them conditionally so that they only appear on the client render.
What it means
Fizz's renderNodeDestructive throws immediately (error code 257) for REACT_PORTAL_TYPE elements: portals need a live DOM target node, which does not exist during server rendering.
Source
Thrown at packages/react-server/src/ReactFizzServer.js:3578
debugTask.run(
renderElement.bind(
null,
request,
task,
keyPath,
type,
props,
ref,
),
);
} else {
renderElement(request, task, keyPath, type, props, ref);
}
}
return;
}
case REACT_PORTAL_TYPE:
throw new Error(
'Portals are not currently supported by the server renderer. ' +
'Render them conditionally so that they only appear on the client render.',
);
case REACT_LAZY_TYPE: {
const lazyNode: LazyComponentType<any, any> = node as any;
let resolvedNode;
if (__DEV__) {
resolvedNode = callLazyInitInDEV(lazyNode);
} else {
const payload = lazyNode._payload;
const init = lazyNode._init;
resolvedNode = init(payload);
}
if (request.aborted) {
// eslint-disable-next-line no-throw-literal
throw null;
}
// Now we render the resolved nodeView on GitHub (pinned to eafeac097b)
Solutions
- Mount portals only on the client: render them after mount (useEffect plus a mounted flag) or behind a typeof document check
- Return null for the overlay during SSR and let the client hydrate/mount it
- Mark the portal-hosting component 'use client' and mount it after hydration
Example fix
// before
function Modal({children}) {
return ReactDOM.createPortal(children, document.body); // throws during SSR
}
// after
function Modal({children}) {
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return null; // no portal on the server
return ReactDOM.createPortal(children, document.body);
} Defensive patterns
Strategy: fallback
Validate before calling
const canUseDOM = typeof document !== 'undefined'; // render portal subtrees only when canUseDOM is true return canUseDOM ? ReactDOM.createPortal(children, document.body) : null;
Prevention
- Never touch document during render; do DOM work in effects
- Assume every component may be server rendered; guard DOM-only APIs
- Mount overlays after a mounted flag flips in useEffect
When it happens
Trigger: Rendering the return value of ReactDOM.createPortal(...) during SSR; a shared modal/tooltip/menu component that unconditionally mounts a portal in its render output.
Common situations: Design-system overlays used inside server-rendered trees; components run through renderToString/renderToStaticMarkup in tests; forgetting that SSR has no document object.
Related errors
- DevTools tooltip root node not found: can't display the cont
- File/Blob fields are not yet supported in progressive forms.
- Can only set one of `children` or `props.dangerouslySetInner
- `props.dangerouslySetInnerHTML` must be in the form `{__html
- input is a self-closing tag and must neither have `children`
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/304029b73df6c11f.
Report an issue: GitHub.