facebook/react · error · Error
The `<head>` tag may only be rendered once.
Error message
The `<head>` tag may only be rendered once.
What it means
Thrown by pushStartHead when a second document-level <head> begins rendering. The first <head> at document position stores its chunks on the request's preamble (preamble.headChunks); a second one finds that slot occupied and throws, because the HTML document model allows exactly one head. This check only applies while insertionMode < HTML_MODE, i.e. heads rendered in the document preamble position rather than inside body content.
Source
Thrown at packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js:3740
// These are used by the client if we clear a boundary and we find these, then we
// also clear the singleton as well.
const headPreambleContributionChunk = stringToPrecomputedChunk('<!--head-->');
const bodyPreambleContributionChunk = stringToPrecomputedChunk('<!--body-->');
const htmlPreambleContributionChunk = stringToPrecomputedChunk('<!--html-->');
function pushStartHead(
target: Array<Chunk | PrecomputedChunk>,
props: Object,
renderState: RenderState,
preambleState: null | PreambleState,
formatContext: FormatContext,
): ReactNodeList {
if (formatContext.insertionMode < HTML_MODE) {
// This <head> is the Document.head and should be part of the preamble
const preamble = preambleState || renderState.preamble;
if (preamble.headChunks) {
throw new Error(`The ${'`<head>`'} tag may only be rendered once.`);
}
// Insert a marker in the body where the contribution to the head was in case we need to clear it.
if (preambleState !== null) {
target.push(headPreambleContributionChunk);
}
preamble.headChunks = [];
return pushStartSingletonElement(
preamble.headChunks,
props,
'head',
formatContext,
);
} else {
// This <head> is deep and is likely just an error. we emit it inline though.
// Validation should warn that this tag is the the wrong spot.
return pushStartGenericElement(target, props, 'head', formatContext);View on GitHub (pinned to eafeac097b)
Solutions
- Render <head> exactly once, in the root layout, and let other components contribute via hoistable metadata (<title>, <meta>, <link> hoist automatically to it)
- Search the tree for all <head> occurrences and delete the duplicates
- If multiple modules need head content, hoist individual tags (<title>, <meta>) instead of a second <head>
Example fix
// before (root layout)
<html><head>...</head><body>{children}</body></html>
// plus a page also rendering <head>...</head>
// after: head only in the root layout
// page.jsx
<>
<title>Page</title>
<meta name="x" content="y" />
</> Defensive patterns
Strategy: validation
Validate before calling
// enforce a single <head> across the app: only the root layout renders it
let headRendered = false;
function DocumentHead() {
if (headRendered) throw new Error('Only one <head> allowed; hoist <title>/<meta> instead');
headRendered = true;
return <head />;
} Prevention
- Render <head> once, in the root layout only
- Let metadata components hoist <title>/<meta>/<link> instead of wrapping them in their own <head>
- Codemod/grep for '<head' across layouts and pages during framework migrations
When it happens
Trigger: Server-rendering a tree that contains <head> twice at the top level — e.g. a root layout rendering <html><head>...</head> while a nested layout/route also renders <head>, or two components each emitting their own <head> before the body starts.
Common situations: Framework layouts where both the shell and a page try to own <head>; adopting a head-manager library alongside an explicit <head>; refactors that moved a head-rendering component into a route rendered together with an existing one.
Related errors
- The `<body>` tag may only be rendered once.
- The `<html>` tag may only be rendered once.
- 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
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/090715e27cd91de7.
Report an issue: GitHub.