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

  1. Give the anchor text or a label: `<a href="/help" aria-label="Help">?</a>`.
  2. For icon-only links, add `aria-label` naming the destination.
  3. Ensure the content is not `aria-hidden` or `display:none`-equivalent from the screen reader's perspective.
  4. 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

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


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/d66ac985c0d53cdf. Report an issue: GitHub.