All rules

Sheath rule

best-practices-button-type

Buttons should have an explicit type attribute to prevent accidental form submission.
Package
Core
Default severity
warning by default
Auto-fix
Auto-fix available

#Why

Without an explicit type, buttons default to type="submit" inside forms, which can cause accidental form submissions when users click buttons intended for other purposes (like opening modals or toggling content).

#Examples

#Bad

<!-- Missing type attribute -->
<button>Click me</button>
<!-- Inside a form, this will submit the form -->
<form>
<button>Open Modal</button>
</form>
<!-- Invalid type value -->
<button type="link">Go somewhere</button>

#Good

<!-- Explicit button type -->
<button type="button">Click me</button>
<!-- Submit button -->
<button type="submit">Submit Form</button>
<!-- Reset button -->
<button type="reset">Clear Form</button>

#Valid Type Values

Set type according to the action the button should perform.

Value Behavior
button Does nothing by default - requires JavaScript
submit Submits the containing form
reset Resets the form to default values

#Auto-fix

The fixer adds the type the button already has implicitly. A button inside a <form> (or associated with one through the form attribute) is a submit button, so it gets type="submit"; any other button gets type="button":

<!-- Before -->
<button>Click me</button>
<form method="post"><button>Save</button></form>
<!-- After -->
<button type="button">Click me</button>
<form method="post"><button type="submit">Save</button></form>

One case is marked dangerous rather than safe: a button with no <form> ancestor in a file that is a fragment (no <html>/<body> in sight). A partial's submit button looks exactly like that because the form lives in the template that includes it. Adding type="button" would silently stop the form from submitting. That fix only runs with --dangerous. In a full page, a button outside every form provably submits nothing, so the type="button" fix stays safe there.

#References

#Notes

  • Missing type is not reported when button attributes are generated dynamically, such as with {{ $attributes->merge(['type' => 'submit']) }} or @if

#Related Rules