oxc-project/oxc · warning · OxcDiagnostic
Disallow string literals in JSX attributes
Error message
Disallow string literals in JSX attributes
What it means
Attribute-case diagnostic of react/jsx-no-literals. It fires when noAttributeStrings is true (default false) and a JSX attribute is assigned a plain string literal, e.g. <input placeholder="Search" />. Like the children case, the goal is i18n and auditability: attribute values that users see should come from an expression (such as a translation function) rather than a hard-coded string. The help text says to replace the literal with a non-literal expression.
Source
Thrown at crates/oxc_linter/src/rules/react/jsx_no_literals.rs:35
use oxc_semantic::SymbolId;
use oxc_span::Span;
use oxc_str::CompactStr;
use crate::{
AstNode,
context::LintContext,
rule::{DefaultRuleConfig, Rule},
utils::{default_true, is_react_component_name},
};
fn literal_text_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Disallow literal text as JSX children")
.with_help("Wrap this text in a JSX expression container, such as a call to a translation function.")
.with_label(span)
}
fn literal_attribute_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Disallow string literals in JSX attributes")
.with_help("Replace this string literal with a non-literal expression, such as a call to a translation function.")
.with_label(span)
}
fn restricted_attribute_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Disallow string literals on restricted JSX attributes")
.with_help("This attribute is listed in `restrictedAttributes`; replace its string literal value with a non-literal expression.")
.with_label(span)
}
/// The options shared between the top-level config and each `elementOverrides` entry.
#[derive(Debug, Default, Clone, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct JsxNoLiteralsOptions {
/// (default: false) - Enforces no string literals used as children, wrapped or unwrapped.
no_strings: bool,
/// An array of unique string values that would otherwise warn, but will be ignored.
allowed_strings: Vec<CompactStr>,View on GitHub (pinned to e1e7af627c)
Solutions
- Replace the literal attribute value with an expression: placeholder={t('search.placeholder')}
- Whitelist genuinely local literals (symbols, constants) via allowedStrings
- Relax specific components with elementOverrides (e.g. allow a design-system Button's label)
- Turn the option off (noAttributeStrings defaults to false) if attribute strings are acceptable
Example fix
// before (noAttributeStrings: true)
<input placeholder="Search" />
// after
<input placeholder={t('search.placeholder')} /> Defensive patterns
Strategy: validation
Validate before calling
npx oxlint -D react/jsx-no-literals src/ # with noAttributeStrings: true
Prevention
- Keep user-visible attribute values (placeholder, alt, title, labels) sourced from the i18n layer
- Set allowedStrings for stable literals like units and symbols to avoid noise
- Remember ignoreProps and noAttributeStrings are separate switches — decide once, in config, which side each attribute class falls on
When it happens
Trigger: Config { "noAttributeStrings": true } plus any attribute with a StringLiteral value: <img alt="Logo"/>, <input placeholder="Email"/>, <Button label="Save"/>. Values in allowedStrings are exempt; elementOverrides can relax specific elements.
Common situations: Extending a no-literals i18n policy from children to attributes; UI libraries whose visible labels (aria-label, title, placeholder) must be translated; migrating from eslint-plugin-react configs where this was the noStrings+ignoreProps interplay — here it is a dedicated noAttributeStrings flag.
Related errors
- Disallow literal text as JSX children
- Disallow string literals on restricted JSX attributes
- `button` elements must have an explicit `type` attribute.
- `button` elements must have a valid `type` attribute.
- `checked` should be used with either `onChange` or `readOnly
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/9678b4654e3a2335.
Report an issue: GitHub.