RMD028 — An element the HTML parser is not allowed to keep here
<p>
intro
<div>a block</div> {/* reported */}
</p>
The client builds the DOM with appendChild, which puts a node exactly where it is told. A parser
does not:
your markup: <p>intro<div>a block</div></p>
what a browser
builds from it: <p>intro</p><div>a block</div>
The <p> is closed early and the <div> becomes its sibling. So this works perfectly until the
page is server-rendered, and then the DOM the browser built is not the tree render() described.
Without this, what you would see at that point is
RMD007 — a mismatch — whose advice is about new Date() and
typeof window. Neither is the problem: the server sent the right markup and the parser moved it.
What is reported, and what the parser does with each:
| markup | what happens |
|---|---|
a block element inside <p> | the <p> is closed; the block becomes its sibling |
<li> outside <ul> / <ol> / <menu> | relocated |
<tr> outside a table, <td> outside a <tr> | relocated |
<option> outside <select> / <optgroup> / <datalist> | relocated |
<form> inside <form> | the inner one is dropped; its fields join the outer form |
<a> inside <a> | the outer link is closed where the inner one starts |
"A block element" is every tag that closes a <p> by the parser's own rule — div, ul, ol,
table, h1–h6, blockquote, form, hr, section, article, pre, figure, and the rest
of flow content. Inline content — <strong>, <em>, <a>, <span> — is fine inside a <p>, which
is what a <p> is for.
Put the element where the parser allows it. A block beside the paragraph rather than inside it, list items in a list, rows in a table. A component in between is invisible to this: what it renders is what the parser sees, so the pair reported is the real parent and the real child however many components sit between them in your JSX.
Next
- All diagnostics — every code the framework can report.
- Checking your app — the faults proved from the source, before anything runs.