How to prevent buttons from submitting forms
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A <button> element inside a <form> submits the form by default. This catches developers off guard because the HTML spec sets the default type attribute of a button to submit, not button. Every approach for preventing this behavior boils down to one idea: tell the browser that a particular button is not a submit trigger. The three main techniques are setting type="button", calling event.preventDefault() in JavaScript, and using the formaction attribute to redirect submission. Each fits different scenarios depending on how much control you need.
Why Buttons Submit Forms by Default
The HTML specification defines three valid values for a button's type attribute:
submitsends the form data to the server. This is the default whentypeis omitted.buttondoes nothing on its own. It exists purely as a JavaScript hook.resetclears all form fields back to their initial values.
Because submit is the implicit default, any <button> placed inside a <form> without an explicit type attribute acts as a submit trigger. This is the root cause of most unintended form submissions.
Method 1: Set type="button"
The simplest and most reliable solution is to explicitly set type="button" on any button that should not trigger form submission. This requires zero JavaScript and works in every browser.
This is the recommended approach for the majority of cases. It is declarative, easy to audit, and has no runtime cost.
Method 2: event.preventDefault() in JavaScript
When you need conditional logic, such as running validation before deciding whether to submit, event.preventDefault() gives you programmatic control. This method works on both button clicks and the form's own submit event.
Preventing on button click
Preventing on form submit
Intercepting the form's submit event is more robust because it catches submissions triggered by the Enter key, not just button clicks.
React equivalent
In React, the pattern is identical but uses synthetic events:
Method 3: The formaction Attribute
HTML5 introduced formaction, which lets a button override the form's action URL. While not a prevention technique per se, it solves the related problem of having multiple submit buttons that send data to different endpoints.
This avoids the need for JavaScript to reroute submissions and keeps the form semantic.
Comparison of Methods
| Method | Requires JavaScript | Conditional Logic | Browser Support | Best For |
type="button" | No | No | All browsers | Static non-submit buttons |
event.preventDefault() | Yes | Yes | All browsers | Validation, async submission |
return false (inline) | Inline JS | Limited | All browsers | Legacy codebases only |
formaction | No | No | HTML5+ | Multiple submit endpoints |
Full Working Example
Here is a complete example combining multiple techniques in a single form. The "Add Item" button dynamically inserts rows without submitting. The "Submit Order" button runs client-side validation first.
Common Pitfalls
Forgetting that the default type is submit. This is the number one cause of unexpected form submissions. Every <button> inside a form should have an explicit type attribute, even if it is type="submit". Being explicit prevents ambiguity.
Using return false in modern code. The inline return false technique only works when the handler is assigned via an onclick attribute. It does not work with addEventListener. Mixing these styles in a codebase leads to inconsistent behavior.
Calling preventDefault on the wrong event. Preventing the button's click event stops that specific button from submitting, but the user can still submit the form by pressing Enter in a text input. If you need to block all submission paths, listen on the form's submit event instead.
Nesting forms. HTML does not allow nested <form> elements. If you accidentally nest forms, browser behavior becomes unpredictable and buttons may submit the wrong form or no form at all.
Disabling buttons instead of changing their type. Setting disabled on a button does prevent submission, but it also prevents all interaction and changes the visual appearance. Use type="button" when you still want the button to be clickable.
Summary
The default type of a <button> in HTML is submit, which causes unintended form submissions when buttons are placed inside forms without an explicit type. The most reliable fix is setting type="button" on every button that should not submit. For dynamic validation or conditional submission, use event.preventDefault() on the form's submit event. Always prefer explicit type attributes over JavaScript workarounds, and audit your forms to ensure every button has a clearly defined role.

