<input> can submit the whole form under HTML's implicit submission rules. Use type="button" on non-submit buttons, then add one keydown listener on the form that blocks Enter only on text-like inputs—not on textarea or IME composition. React and Vue can mirror the same checks on the form element.Point any HTML form at one endpoint. 500 free submissions — no card, no time limit — and unlimited forms.
Create free accountWhy Enter submits your form
Browsers follow the HTML spec's implicit submission rule. When the user presses Enter in a single-line text field inside a <form>, the browser submits that form if any of these are true:
- The form has a submit control (a
<button type="submit">, an<input type="submit">, or a<button>with notypeattribute—the default is submit). - Or the form has exactly one single-line text field and no submit button (Enter still submits).
Enter inside a <textarea> never submits; it inserts a new line. That distinction matters when you add JavaScript to block Enter: you must not break textarea editing.
Accidental submits often show up alongside duplicate POSTs; see prevent duplicate form submissions. Multi-step flows are a common trigger—multi-step form HTML, CSS and JavaScript covers patterns where Enter on step one should not fire the whole submit.
Fix 2: keydown on the form (recommended)
Attach one keydown listener to the form. Call e.preventDefault() when the key is Enter, the event target is an INPUT, and the input's type is not submit, button, checkbox, or radio. Do not run this for TEXTAREA. Skip events where e.isComposing is true so Chinese, Japanese, and Korean IME users can confirm composed text with Enter.
const form = document.querySelector("form");
form.addEventListener("keydown", (e) => {
if (e.key !== "Enter" || e.isComposing) return;
const el = e.target;
if (!(el instanceof HTMLInputElement)) return;
const skipTypes = new Set(["submit", "button", "checkbox", "radio"]);
if (skipTypes.has(el.type)) return;
e.preventDefault();
});The submit button still works: clicking it (or focusing it and activating it) runs a normal submit. Only Enter inside single-line inputs is blocked. For the difference between programmatic submit() and user-driven submission, see form.submit() vs requestSubmit().
Fix 3: Enter moves to the next field
Some data-entry UIs want Enter to behave like Tab. After preventDefault(), focus the next control in form.elements:
form.addEventListener("keydown", (e) => {
if (e.key !== "Enter" || e.isComposing) return;
const el = e.target;
if (!(el instanceof HTMLInputElement)) return;
if (["submit", "button", "checkbox", "radio"].includes(el.type)) return;
e.preventDefault();
const fields = [...form.elements].filter(
(node) =>
node instanceof HTMLInputElement ||
node instanceof HTMLSelectElement ||
node instanceof HTMLTextAreaElement
);
const i = fields.indexOf(el);
if (i >= 0 && i < fields.length - 1) fields[i + 1].focus();
});Keep a visible submit control on the last step so users who expect Enter to submit on a simple form are not surprised on the final field.
React and Vue
React: put the same logic on the form's onKeyDown:
function BlockEnterSubmit({ children }: { children: React.ReactNode }) {
return (
<form
onKeyDown={(e) => {
if (e.key !== "Enter" || e.nativeEvent.isComposing) return;
const t = e.target;
if (!(t instanceof HTMLInputElement)) return;
if (["submit", "button", "checkbox", "radio"].includes(t.type)) return;
e.preventDefault();
}}
>
{children}
</form>
);
}Vue 3: you can use @keydown.enter on a specific input with .prevent, but that blocks Enter only on that field. For the whole form, use @keydown on <form> with the same target checks as above. Per-input: @keydown.enter.prevent on a search box is fine when the form has a separate Search button.
Why not onsubmit return false?
Returning false from onsubmit or calling preventDefault() on every submit event stops all submissions—including when the user clicks the submit button or presses Enter on purpose. The keydown approach is narrower: it targets accidental Enter in text fields only.
Accessibility: keyboard users often rely on Enter to submit a short contact or login form. Only disable implicit Enter where accidental submits cause real harm (partial multi-step data, warehouse scanners, inline grids). Always leave a clear submit action and test with the keyboard alone.
Ship a form that actually posts
Blocking Enter does not replace a working endpoint. Point your action at a handler that accepts POST, or send FormData with fetch after preventDefault() on submit. Get a free splitforms access key and POST to https://splitforms.com/api/submit. For button types and defaults, see the <button> reference.
FAQ
Why does pressing Enter submit my form?
HTML implicit submission: when you press Enter in a single-line text field, the browser submits the form if it has a submit button, or if the form has only one single-line field. That is by design so keyboard users can submit without tabbing to the button.
How do I stop Enter submitting but keep new lines in a textarea?
Enter in a textarea never triggers implicit submission; it inserts a newline. If you add a keydown listener on the form, skip TEXTAREA (and skip INPUT types like submit and checkbox). Only call preventDefault on Enter for single-line inputs where accidental submit is the problem.
Is disabling Enter bad for accessibility?
Often yes. Many users expect Enter to submit a simple form. Block Enter only where accidental submits are common (multi-step wizards, barcode scanners, dense data entry). Keep a visible submit button and do not block Enter on the final step unless you have a clear alternative.
How do I stop Enter submitting in React?
Put the same keydown logic on the form’s onKeyDown handler: if key is Enter, target is an INPUT (not submit/button/checkbox/radio), and not isComposing, call preventDefault. Do not use onSubmit return false—that blocks intentional button submits too.
Spec: HTML implicit submission.