{"record":{"id":"9d88a922de3e8f3b","repo":"oxc-project/oxc","slug":"button-elements-must-have-an-explicit-type-att","errorCode":null,"errorMessage":"`button` elements must have an explicit `type` attribute.","messagePattern":"`button` elements must have an explicit `type` attribute\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/react/button_has_type.rs","lineNumber":21,"sourceCode":"    context::{ContextHost, LintContext},\n    rule::{DefaultRuleConfig, Rule},\n    utils::{get_prop_value, has_jsx_prop_ignore_case, is_create_element_call},\n};\nuse oxc_ast::{\n    AstKind,\n    ast::{\n        Argument, Expression, JSXAttributeItem, JSXAttributeValue, JSXElementName,\n        ObjectPropertyKind,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\nuse schemars::JsonSchema;\nuse serde::Deserialize;\n\nfn missing_type_prop(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"`button` elements must have an explicit `type` attribute.\")\n        .with_help(\"Add a `type` attribute to the `button` element.\")\n        .with_label(span)\n}\n\nfn invalid_type_prop(span: Span, allowed_types: &str) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"`button` elements must have a valid `type` attribute.\")\n        .with_help(format!(\n            \"Change the `type` attribute to one of the allowed values: {allowed_types}.\"\n        ))\n        .with_label(span)\n}\n\n#[derive(Debug, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct ButtonHasType {\n    /// If true, allow `type=\"button\"`.\n    button: bool,\n    /// If true, allow `type=\"submit\"`.","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/react/button_has_type.rs#L3-L39","documentation":"Diagnostic from the oxlint rule `react/button-has-type` (plugin `react`, category `restriction`). It fires on JSX `<button>` opening elements (only identifier-named elements; member/namespace names are skipped) that lack a `type` attribute (looked up case-insensitively), and on `createElement(\"button\", ...)` calls where the second (props) argument is missing. The rule only runs for JSX sources (`should_run` checks `source_type().is_jsx()`). The HTML default for `type` is `\"submit\"`, which inside a `<form>` causes unexpected page reloads/submissions; the rule's stance is that the intent must be explicit even though all three values are allowed by default.","triggerScenarios":"`<button>Save</button>`; `<button {...props} />` with no explicit type attribute; `React.createElement('button')` without a props argument; any `<button>` whose attributes contain no `type`.","commonSituations":"Buttons inside forms triggering surprise submits; design-system button components forwarding props; JS-to-TSX conversions where attributes were dropped.","solutions":["Add an explicit `type`: `<button type=\"button\">Save</button>` (or `type=\"submit\"` / `type=\"reset\"`)","In `createElement` calls, pass a props object containing `type`","If buttons appear outside forms and you accept the implicit default, still add `type` to satisfy the rule and document intent"],"exampleFix":"// before\n<button onClick={save}>Save</button>\n\n// after\n<button type=\"button\" onClick={save}>Save</button>","handlingStrategy":"validation","validationCode":"npx oxlint --react/button-has-type src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make `type` part of your button component's required props (forward it to the DOM element)","Remember the implicit default is `type=\"submit\"` inside forms","Add explicit `type` when authoring; the rule fires even when props come from spread"],"tags":["react","jsx","html","lint","forms","oxlint"],"backgroundTag":"button-missing-type-attribute","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}