Use standard HTML attributes for instant, browser-based validation. This helps check if required fields are filled in and if emails are valid, without any extra code.
Example:
<form data-form="contact"> <label for="email">Email:</label> <input id="email" name="email" type="email" required> <button type="submit">Send</button> <div id="form-message" aria-live="polite"></div></form>type="email": Checks for valid email format.required: Makes the field mandatory.Try this out in different browsers to see how each browser handles these native validations.
To provide a friendlier message if the email is not valid, add a small script:
const form = document.querySelector('[data-form="contact"]');if (form) {const email = form.querySelector('input[type="email"]');email.addEventListener('input', function() {email.setCustomValidity(''); // Clear any custom messageif (!email.checkValidity()) {email.setCustomValidity('Please enter a valid email address.'); } });form.addEventListener('submit', function(e) {if (!form.checkValidity()) {e.preventDefault(); // Stop form from submittingform.reportValidity(); // Show errors } });}What this does:
For extra security, send form data to a server endpoint instead of directly from the browser. This keeps sensitive information safe.
form.addEventListener('submit', function(e) {e.preventDefault();if (!form.checkValidity()) {form.reportValidity();return; }const button = form.querySelector('button[type="submit"]');button.disabled = true; // Prevent double submissionfetch('/api/contact', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: email.value }) }) .then(response => {if (!response.ok) throw new Error('Network error'); document.getElementById('form-message').textContent = 'Thanks! Your message has been sent.';form.reset(); }) .catch(() => { document.getElementById('form-message').textContent = 'Sorry, something went wrong. Please try again.'; }) .finally(() => {button.disabled = false; });});Tips:
aria-live="polite" on a message area to read out results to screen readers.Can I keep using Webflow's normal form submission?
How do I prevent spam?
Will this stop browser validation?
preventDefault() in your script, the browser will still check the form for you.