{"record":{"id":"d66ac985c0d53cdf","repo":"oxc-project/oxc","slug":"missing-accessible-content-when-using-a-elements","errorCode":null,"errorMessage":"Missing accessible content when using `a` elements.","messagePattern":"Missing accessible content when using `a` elements\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/jsx_a11y/anchor_has_content.rs","lineNumber":25,"sourceCode":"};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\nuse oxc_str::CompactStr;\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    fixer::{Fix, RuleFix},\n    rule::{DefaultRuleConfig, Rule},\n    utils::{\n        get_element_type, has_jsx_prop_ignore_case, is_hidden_from_screen_reader,\n        object_has_accessible_child,\n    },\n};\n\nfn missing_content(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Missing accessible content when using `a` elements.\")\n        .with_help(\"Provide screen reader accessible content when using `a` elements.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone, Deserialize)]\npub struct AnchorHasContent(Box<AnchorHasContentConfig>);\n\n#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct AnchorHasContentConfig {\n    /// Additional custom component names to treat as anchor elements.\n    components: Vec<CompactStr>,\n}\n\nimpl std::ops::Deref for AnchorHasContent {\n    type Target = AnchorHasContentConfig;\n\n    fn deref(&self) -> &Self::Target {","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/jsx_a11y/anchor_has_content.rs#L7-L43","documentation":"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.","triggerScenarios":"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.","commonSituations":"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`.","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\"] }]`."],"exampleFix":"// before\n<a href=\"/help\"><i className=\"icon icon-help\" /></a>\n\n// after\n<a href=\"/help\" aria-label=\"Help\"><i className=\"icon icon-help\" aria-hidden=\"true\" /></a>","handlingStrategy":"validation","validationCode":"// Link wrapper guaranteeing accessible content\ntype A11yLinkProps = { href: string; label?: string; children?: React.ReactNode };\nexport function A11yLink({ href, label, children }: A11yLinkProps) {\n  const hasText = Boolean(label ?? children);\n  if (!hasText) throw new Error('A11yLink requires label or children');\n  return <a href={href} aria-label={label}>{children}</a>;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["jsx-a11y","accessibility","link-text","screen-reader","react","lint","oxlint"],"backgroundTag":"jsx-a11y-anchor-has-content","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}