Skip to main content
interlace
Plugin: react-featuresRules

no-invalid-html-attribute

no-invalid-html-attribute rule

Use React's camelCase name for HTML attributes React renames. This rule is part of eslint-plugin-react-features.

Quick Summary

AspectDetails
SeverityWarning (correctness)
Auto-Fix💡 Suggests corrections
CategoryReact
ESLint MCP✅ Optimized for ESLint MCP integration
Best ForHTML/JSX correctness, accessibility

Rule Details

On a DOM element React expects the camelCase prop name and warns for the HTML spelling ("Invalid DOM property class. Did you mean className?"). The rule reports an attribute written with the HTML spelling of a name React renames — class, for, tabindex, readonly, maxlength, colspan, http-equiv, accept-charset, crossorigin, srcset and the rest of React's list.

A custom element (a tag name with a hyphen, <my-widget>, or an element with is="…") is not checked: React sets its attributes as written, so the HTML spelling is the right one there. Attribute values are not validated.

Examples

❌ Incorrect

<label for="input-id">Label</label>
<div class="card" tabindex="0" />
<meta http-equiv="refresh" content="5" />

✅ Correct

<label htmlFor="input-id">Label</label>
<div className="card" tabIndex={0} />
<meta httpEquiv="refresh" content="5" />
<my-widget class="card" />

Configuration Examples

Basic Usage

{
  rules: {
    'react-features/no-invalid-html-attribute': 'warn'
  }
}

Further Reading

Known False Negatives

  • Spread attributes: <label {...{ for: id }} /> is not read.
  • Names outside the list: only the HTML spellings React renames (class, for, tabindex, readonly, maxlength, http-equiv, …) are checked; attribute values are not validated.

Not reported by design: any attribute on a custom element (<my-widget class="x">, <button is="fancy-button">), where React sets attributes as written. The rule does report the same names on a component (<Label for="x">), whose props may never reach the DOM.

Use this rule

npm install -D oxlint-plugin-react-features
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-react-features"],  "rules": {    "react-features/no-invalid-html-attribute": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-react-features'],    rules: {      'react-features/no-invalid-html-attribute': 'error',    },  },});

oxlint-plugin-react-features re-exports eslint-plugin-react-features/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.