react/jsx-no-literals
Disallow text written directly in JSX
Text typed straight into JSX never goes through your translation function, so every user sees it in the language you wrote it in.
By default the rule only reports bare text between tags. It treats a string in braces, such as {"Bun"}, as written on purpose. The noStrings option reports those too.
Configure#
Off by default. To turn it on:
[lint.rules]
"react/jsx-no-literals" = "error" # or "warn"Every option, set to its default:
[lint.rules]
"react/jsx-no-literals" = ["error", {
noStrings = false,
ignoreProps = false,
noAttributeStrings = false,
allowedStrings = [], # list of strings
elementOverrides = {},
}]Examples#
function Greeting() {
return <p>Welcome backMissing JSX expression container around literal string: "Welcome back"</p>;
}function Greeting({ t }) {
return <p>{t("greeting.welcome")}</p>;
}
const brand = <strong>{"Bun"}</strong>;Options#
| Option | Default | What it does |
|---|---|---|
noStrings | false | Also report strings and template literals in braces, and strings in props. |
ignoreProps | false | Never report anything in props. |
noAttributeStrings | false | Also report props with a plain string value, such as alt="Logo". |
allowedStrings | [] | Strings that are never reported. Spaces around the text don't count. |
elementOverrides | {} | Different options for some components, by name. |
restrictedAttributes | [] | Only for an oxlint config. Props that can't have a plain string value, even with ignoreProps. bunfig.toml rejects this option. |
With noStrings, braces don't help:
{ "noStrings": true }2 problemsfunction Greeting() {
return <p title="Greeting"Invalid prop value: "title="Greeting"">{"Welcome back"Strings not allowed in JSX files: ""Welcome back""}</p>;
}{ "noStrings": true, "ignoreProps": true }No problemsfunction Greeting({ t }) {
return <p title="Greeting">{t("greeting.welcome")}</p>;
}noAttributeStrings looks at props without the rest of noStrings:
{ "noAttributeStrings": true }1 problemconst logo = <img src={logoUrl} alt="Company logo"Strings not allowed in attributes: ""Company logo"" />;allowedStrings is for punctuation and other text that's the same in every language:
{ "allowedStrings": ["|"] }No problemsconst links = (
<nav>
{home} | {about}
</nav>
);elementOverrides#
The keys are component names, which start with a capital letter. Each value takes the options above, which replace the top-level ones for that component, plus two more:
| Option | Default | What it does |
|---|---|---|
allowElement | false | Allow text in this component. |
applyToNestedElements | true | Use these options for the elements inside the component too. |
{ "elementOverrides": { "Trans": { "allowElement": true } } }No problemsconst message = (
<Trans>
Welcome <b>back</b>
</Trans>
);{ "elementOverrides": { "Trans": { "allowElement": true, "applyToNestedElements": false } } }1 problemconst message = (
<Trans>
Welcome <b>backMissing JSX expression container around literal string: back</b>
</Trans>
);An empty override resets a component to the defaults, so here it's checked without noStrings:
{ "noStrings": true, "elementOverrides": { "Code": {} } }No problemsconst command = <Code>{"bun lint"}</Code>;When not to use it#
If your app is in one language and stays that way, text in JSX is fine.