oxc-project/oxc · warning
Missing accessible content when using `a` elements.
Error message
Missing accessible content when using `a` elements.
What it means
This is the oxlint `jsx-a11y/anchor-has-content` diagnostic. An anchor is announced as a link only if it has something perceivable inside; elements hidden from screen readers or anchors with no text/image content are unreachable or meaningless to assistive technology. The rule reports `<a>` (and configured custom components) whose accessible content is empty.
Source
Thrown at crates/oxc_linter/src/rules/jsx_a11y/anchor_has_content.rs:25
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use oxc_str::CompactStr;
use crate::{
AstNode,
context::LintContext,
fixer::{Fix, RuleFix},
rule::{DefaultRuleConfig, Rule},
utils::{
get_element_type, has_jsx_prop_ignore_case, is_hidden_from_screen_reader,
object_has_accessible_child,
},
};
fn missing_content(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Missing accessible content when using `a` elements.")
.with_help("Provide screen reader accessible content when using `a` elements.")
.with_label(span)
}
#[derive(Debug, Default, Clone, Deserialize)]
pub struct AnchorHasContent(Box<AnchorHasContentConfig>);
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct AnchorHasContentConfig {
/// Additional custom component names to treat as anchor elements.
components: Vec<CompactStr>,
}
impl std::ops::Deref for AnchorHasContent {
type Target = AnchorHasContentConfig;
fn deref(&self) -> &Self::Target {View on GitHub (pinned to e1e7af627c)
Solutions
- Give the anchor text or a label: `<a href="/help" aria-label="Help">?</a>`.
- For icon-only links, add `aria-label` naming the destination.
- Ensure the content is not `aria-hidden` or `display:none`-equivalent from the screen reader's perspective.
- Register wrapper components: `"jsx-a11y/anchor-has-content": ["error", { "components": ["Link", "NavLink"] }]`.
Example fix
// before <a href="/help"><i className="icon icon-help" /></a> // after <a href="/help" aria-label="Help"><i className="icon icon-help" aria-hidden="true" /></a>
Defensive patterns
Strategy: validation
Validate before calling
// Link wrapper guaranteeing accessible content
type A11yLinkProps = { href: string; label?: string; children?: React.ReactNode };
export function A11yLink({ href, label, children }: A11yLinkProps) {
const hasText = Boolean(label ?? children);
if (!hasText) throw new Error('A11yLink requires label or children');
return <a href={href} aria-label={label}>{children}</a>;
} Prevention
- For icon-only anchors always add `aria-label` naming the destination.
- Mark decorative icons inside links `aria-hidden="true"` while keeping a real label.
- Register custom link components in the rule's `components` config so wrappers are checked.
- Watch for content that becomes screen-reader-hidden via aria-hidden or styles.
When it happens
Trigger: An anchor element resolves with no usable content: no children text, no `title`/`aria-label`/`aria-labelledby`, no accessible child content (an icon-only `<i>` with no text also fails), or its content is hidden from screen readers. Custom components can be added via the rule's `components` option.
Common situations: Icon-only anchors using font-icon libraries (no `aria-label`); anchors whose entire body is `hidden` or `aria-hidden`; `<a>` used as a styled placeholder with empty children; wrappers like `<Link>` not registered in `components`.
Related errors
- Ambiguous text within anchor, screen reader users rely on li
- ARIA used where native HTML could suffice.
- Missing `alt` attribute.
- Invalid `alt` value.
- Missing value for `aria-label` attribute.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/d66ac985c0d53cdf.
Report an issue: GitHub.