oxc-project/oxc · warning
Prefer `{tag}` over `role` attribute `{role}`.
Error message
Prefer `{tag}` over `role` attribute `{role}`. What it means
This is the `jsx_a11y/prefer-tag-over-role` rule in oxlint. It fires when an element with an explicit ARIA role has a native HTML element that provides that role for free (via `get_tags_for_role`), e.g. `<div role="button">`. Native elements carry built-in keyboard behavior and semantics, so the tag is preferred over the role override.
Source
Thrown at crates/oxc_linter/src/rules/jsx_a11y/prefer_tag_over_role.rs:17
use oxc_ast::{
AstKind,
ast::{JSXAttributeItem, JSXAttributeValue},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{
AstNode,
context::LintContext,
rule::Rule,
utils::{get_element_type, get_tags_for_role, has_jsx_prop_ignore_case},
};
fn prefer_tag_over_role_diagnostic(span: Span, tag: &str, role: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Prefer `{tag}` over `role` attribute `{role}`."))
.with_help(format!("Replace HTML elements with `role` attribute `{role}` to corresponding semantic HTML tag `{tag}`."))
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct PreferTagOverRole;
declare_oxc_lint!(
/// ### What it does
///
/// Enforces using semantic HTML tags over `role` attribute.
///
/// ### Why is this bad?
///
/// Using semantic HTML tags can improve accessibility and readability of the code.
///
/// ### Examples
///View on GitHub (pinned to e1e7af627c)
Solutions
- Swap the element for the semantic tag the rule names (e.g. `<button>`, `<nav>`, `<table>`) and drop the `role`.
- Carry over styling via className; reset browser defaults (all: unset / appearance: none) where looks matter.
- If the wrapper structure must stay, keep the interactive tag on the innermost operable node instead.
Example fix
// before
<div role="button" tabIndex={0} onClick={submit}>Submit</div>
// after
<button type="button" onClick={submit}>Submit</button> Defensive patterns
Strategy: validation
Validate before calling
npx oxlint --jsx-a11y/prefer-tag-over-role src/
Prevention
- Start every new interactive component from a semantic tag.
- Treat role overrides on generic containers as code smell in review.
- When the rule names a tag, adopt it rather than suppressing the diagnostic.
When it happens
Trigger: A JSX element (resolved via `get_element_type`) with a `role` attribute whose value maps to one or more recommended semantic tags in the role->tags table, while the element itself is not one of those tags.
Common situations: Div-based buttons (`role="button"`), div headings (`role="heading"`), nav-like divs (`role="navigation"`) written before teams adopted semantic HTML; component libraries overriding roles on generic containers.
Related errors
- Interactive elements should not be assigned non-interactive
- Non-interactive elements should not be assigned interactive
- The `{element}` element has an implicit role of `{role}`. De
- Static HTML elements with event handlers require a role.
- The attribute `{attr_name}` is not supported by the role `{r
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/856adadb1598267a.
Report an issue: GitHub.