Do Not Give Children To An Element That Sets Raw HTML

ID

javascript.react_children_with_dangerously_set_html

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

react, reliability

Description

Reports an element that sets dangerouslySetInnerHTML and also gives children. React accepts one or the other and throws when it is given both.

Rationale

dangerouslySetInnerHTML replaces the element’s content wholesale, so children have nowhere to go. React does not resolve the conflict by preferring one: it throws "Can only set one of children or props.dangerouslySetInnerHTML", which takes down the render of the whole tree.

The children are usually left over from an earlier version of the component — a placeholder, a fallback, a loading label — and survive review because the element still reads sensibly.

This is React’s runtime error, not the injection risk. Whether the HTML being set is trustworthy is a separate question with its own answer; this rule fires the same on safe markup.

What counts as children is what React would receive: text with something other than whitespace in it, a nested element or fragment, an expression in braces, or an explicit children prop. A brace pair holding only a comment passes nothing and does not count. Every element is judged, components included: a component that forwards both props to a DOM node hits the same error one level down.

<div dangerouslySetInnerHTML={{ __html: body }}>Loading</div>      // FLAW - text child
<div dangerouslySetInnerHTML={{ __html: body }}>{fallback}</div>   // FLAW - expression child
<div dangerouslySetInnerHTML={{ __html: body }} children={rest} /> // FLAW - as a prop

<div dangerouslySetInnerHTML={{ __html: body }} />                 // OK
<div>{body}</div>                                                  // OK

Remediation

Pick one. Remove the children when the raw HTML is the content — a placeholder belongs in the branch that renders before the HTML arrives, not alongside it. Or drop the raw-HTML prop and render the content as children, which is the better answer whenever the HTML does not have to be raw. Where both are genuinely needed, put the raw HTML in its own child element and keep the other children beside it.

© 2026 Xygeni. All rights reserved