oxc-project/oxc · warning · OxcDiagnostic

Name "{name}" is reserved in HTML.

Error message

Name "{name}" is reserved in HTML.

What it means

The reserved-in-HTML variant of vue/no-reserved-component-names: 'Name "{name}" is reserved in HTML.' A component named after an HTML element (from VUE_RESERVED_HTML_ELEMENTS, and VUE_RESERVED_SVG_ELEMENTS for SVG tags) shadows that element in in-DOM templates and can be parsed as the native tag instead of your component. By default the match is case-insensitive-ish for capitalized forms (config flag controls case-sensitive matching of HTML/SVG names).

Source

Thrown at crates/oxc_linter/src/rules/vue/no_reserved_component_names.rs:29

use crate::{
    AstNode,
    context::LintContext,
    rule::{DefaultRuleConfig, Rule},
    utils::{
        VUE_RESERVED_DEPRECATED_HTML_ELEMENTS, VUE_RESERVED_HTML_ELEMENTS,
        VUE_RESERVED_KEBAB_CASE_ELEMENTS, VUE_RESERVED_SVG_ELEMENTS, VUE2_BUILTIN_COMPONENT_NAMES,
        VUE3_BUILTIN_COMPONENT_NAMES_EXTRA, find_property,
        is_vue_component_options_object_excluding_instance,
    },
};

fn reserved_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Name \"{name}\" is reserved.")).with_label(span)
}

fn reserved_in_html_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Name \"{name}\" is reserved in HTML.")).with_label(span)
}

fn reserved_in_vue_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Name \"{name}\" is reserved in Vue.js.")).with_label(span)
}

fn reserved_in_vue3_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Name \"{name}\" is reserved in Vue.js 3.x.")).with_label(span)
}

#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoReservedComponentNames {
    /// Disallow Vue 2 built-in component names (e.g. `Transition`, `KeepAlive`).
    disallow_vue_built_in_components: bool,
    /// Disallow Vue 3 built-in component names (e.g. `Teleport`, `Suspense`).
    /// Note: this also catches Vue 2 built-ins because Vue 3's set includes them.
    disallow_vue3_built_in_components: bool,

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Rename the component to a non-reserved name (e.g. `PageHeader`, `IconCircle`).
  2. If you only need the exact tag inside the template, keep the native element and style it instead of shadowing it with a component.
  3. Set the rule's case-sensitivity option deliberately if you accept capitalized collisions in SFC-only templates — but renaming is safer.
  4. Re-run oxlint to confirm.

Example fix

// before
export default {
  name: 'Header' // reserved in HTML
}

// after
export default {
  name: 'PageHeader'
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Naming a component `Div`, `Header`, `Menu`, `Svg`, `Circle`, etc. — anything in the HTML/SVG reserved lists — via the `name` option or the file/registration name, with the rule's case-sensitivity option left at its default (capitalized forms also reported).

Common situations: Wrapper components named `Header` or `Footer` that render those tags; SVG icon components named after SVG elements (`Circle`, `Path`); in-DOM templates (HTML parsed by the browser) where such names resolve to native elements.

Related errors


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