oxc-project/oxc · error · OxcDiagnostic

Missing `href` attribute for the `a` element.

Error message

Missing `href` attribute for the `a` element.

What it means

This is the oxlint `jsx-a11y/anchor-is-valid` diagnostic for anchors with no navigable `href`. Per HTML semantics an `<a>` is a hyperlink between documents/locations; without `href` (or one of the configured valid attributes) it is not focusable or announced as a link, and crawlers cannot follow it. The help text lists the accepted attribute names, which default to `href` and can be widened via the rule's `specialLink`-style config for router `Link` components.

Source

Thrown at crates/oxc_linter/src/rules/jsx_a11y/anchor_is_valid.rs:30

use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use oxc_str::CompactStr;

use crate::{
    AstNode,
    context::LintContext,
    rule::{DefaultRuleConfig, Rule},
    utils::{get_element_type, has_jsx_prop_ignore_case},
};

fn missing_href_attribute<S: AsRef<str>>(span: Span, valid_attrs: &[S]) -> OxcDiagnostic {
    let help = if valid_attrs.len() == 1 {
        format!("Provide the `{}` attribute for the `a` element.", valid_attrs[0].as_ref())
    } else {
        let list = valid_attrs.iter().map(|a| format!("`{}`", a.as_ref())).join(", ");
        format!("Provide one of these attributes for the `a` element: {list}")
    };
    OxcDiagnostic::warn("Missing `href` attribute for the `a` element.")
        .with_help(help)
        .with_label(span)
}

fn incorrect_href(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Use of incorrect `href` for the 'a' element.")
        .with_help("Provide a correct `href` for the `a` element.")
        .with_label(span)
}

fn cant_be_anchor(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("The `a` element has `href` and `onClick`.")
        .with_help("Use a `button` element instead of an `a` element.")
        .with_label(span)
}

#[derive(Debug, Default, Clone, Deserialize)]
pub struct AnchorIsValid(Box<AnchorIsValidConfig>);

View on GitHub (pinned to 1f902a6962)

Solutions

  1. If it navigates, add the real target: `<a href="/pricing">Pricing</a>`.
  2. If it only runs a handler, use a button: `<button onClick={foo}>Perform action</button>`.
  3. For custom link components with a different attribute name, list it in the rule config so `<Link to="...">` is accepted.
  4. Give the anchor a real `href` even when intercepting clicks client-side.

Example fix

// before
<a onClick={openMenu}>Open menu</a>

// after
<button onClick={openMenu}>Open menu</button>
// or, when it really navigates:
<a href="/menu" onClick={handleMenuClick}>Open menu</a>
Defensive patterns

Strategy: validation

Validate before calling

// Guard at authoring time: only render <a> when a target exists
const Anchor = ({ href, children }: { href?: string; children: React.ReactNode }) =>
  href ? <a href={href}>{children}</a> : <button>{children}</button>;

Prevention

When it happens

Trigger: A JSX element resolves to `a` (or a configured component) with no attribute in the valid set — typically `<a onClick={foo}>` with no `href`. Elements whose props come from a spread are not reported (the attribute cannot be proven absent). Aspects are configurable (`noHref`, `invalidHref`, `preferButton`).

Common situations: Using `<a>` as a click target instead of `<button>`; router links where the attribute is `to` instead of `href` and the component isn't configured; drag-handle or tab UIs built on anchors.

Related errors


AI-assisted analysis of oxc-project/oxc@1f902a6962 (2026-09-14). Data as JSON: /api/errors/ade2d30cda441264. Report an issue: GitHub.