jsx-eslint / eslint-plugin-react

React-specific linting rules for ESLint
MIT License
9.01k stars 2.77k forks source link

Proposal: jsx-no-mixed-title #3839

Open jamesarosen opened 1 month ago

jamesarosen commented 1 month ago

This issue describes a common problem that has an easy but non-obvious solution.

  1. Browsers interpret the contents of <title> as literal text.
  2. React uses comments to mark the boundaries between static and dynamic content

Putting (1) and (2) together means that this normal-seeming JSX is broken:

<head>
  <title>Some static text {aVariable} more static text</title>
</head>

react-dom emits a warning:

Warning: A title element received an array with more than 1 element as children. In browsers title Elements can only have Text Nodes as children. If the children being rendered output more than a single text node in aggregate the browser will display markup and comments as text in the title and hydration will likely fail and fall back to client rendering

I propose a rule that allows static text or an interpolation, but not both as the child of <title>.

Valid:
<title>Some static text</title>

Valid:
<title>{aVariable}</title>

Valid:
<title>{`A Template string {isAGreatWay} to combine them`}</title>

Invalid:
<title>Some static text {aVariable} more static text</title>
ljharb commented 1 month ago

tbh this seems like just a bug in React to me - i'm not sure why they can't just omit the comments for <title>, presumably at the insignificant cost of making updates to that element slower or more frequent.

jamesarosen commented 1 month ago

I agree, but the React team knows about it and doesn't want to fix it.