Check an email as someone types
Add email feedback and optional spelling corrections to your existing field with form.js.
On this page
Working example
HTML + form.jsMark your email field
Add the shared script once, then put data-parse="email" on your existing email input. Keep its label, name, and native HTML rules.
<script src="https://cdn.parseapi.com/v1/form.js" data-key="YOUR_PUBLIC_API_KEY" defer></script>
<div class="field">
<label for="email">Email</label>
<input id="email" type="email" name="email" data-parse="email" autocomplete="email" placeholder="you@example.com" required>
</div>Replace YOUR_PUBLIC_API_KEY with a Public key from the example setup. Allow your site's hostname and localhost for local development. Serve the downloaded HTML over HTTP; keep secret keys on your server.
The script checks a complete-looking address after a typing pause or when the field loses focus. A possible spelling correction appears beside the field. The address changes only when the person accepts it.
Keep submission yours
The default preset marks an invalid format, an explicitly invalid mail domain, or a disposable address as invalid through the browser's native form validation. An unknown domain is not a failed check. Your required and type="email" rules still apply.
The script never waits for a pending lookup before submission. If the request is unavailable, it leaves the field unchecked. Your server must validate the submitted value and apply your signup rules.
Try hello@gmail.con to see an optional correction. This checks format and domain signals; it does not prove mailbox delivery or ownership.
For your own validation policy, data-parse-validation="manual" leaves custom validity to your code. Build directly with the Email API when you need a custom integration.
Complete example
One HTML file with your fields, styles, and the form.js include. Replace YOUR_PUBLIC_API_KEY with your public key, then run it on a domain you have added to that key.
View and copy the complete source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Check an email as someone types</title>
<style>
:root { color-scheme: light dark; --bg: #fff; --ink: #152029; --muted: #5e6b75; --line: #d9e2e7; --field: #f6f9fa; --accent: #007c91; --error: #b42335; }
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) { --bg: #0b1015; --ink: #eff7fa; --muted: #94a6b2; --line: #2c3942; --field: #121b23; --accent: #67e8f9; --error: #fda4af; }
}
:root[data-theme="dark"] { color-scheme: dark; --bg: #0b1015; --ink: #eff7fa; --muted: #94a6b2; --line: #2c3942; --field: #121b23; --accent: #67e8f9; --error: #fda4af; }
:root[data-theme="light"] { color-scheme: light; }
* { box-sizing: border-box; }
[hidden] { display: none !important; }
body { margin: 0; padding: 24px; background: var(--bg); color: var(--ink); font: 15px/1.5 system-ui, sans-serif; }
main { max-width: 540px; margin: 0 auto; }
label { display: block; margin-bottom: 8px; font-size: 14px; font-weight: 600; }
input { display: block; width: 100%; min-width: 0; padding: 13px 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--field); color: var(--ink); font: inherit; }
input::placeholder { color: var(--muted); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Your form owns these styles. form.js adds semantic markup and states. */
input[data-parse-status="invalid"], input[data-parse-status="disposable"] { border-color: var(--error); }
.parse-hint { margin: 6px 0 0; color: var(--muted); font-size: .875em; line-height: 1.4; overflow-wrap: anywhere; }
.parse-hint[data-parse-status="invalid"], .parse-hint[data-parse-status="disposable"] { color: var(--error); }
.parse-hint-suggestion { padding: 0; border: 0; background: none; color: inherit; font: inherit; font-weight: 600; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.parse-hint-suggestion:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@media (max-width: 380px) { body { padding: 18px; } }
</style>
</head>
<body>
<main>
<!-- example:form -->
<script src="https://cdn.parseapi.com/v1/form.js" data-key="YOUR_PUBLIC_API_KEY" defer></script>
<div class="field">
<label for="email">Email</label>
<input id="email" type="email" name="email" data-parse="email" autocomplete="email" placeholder="you@example.com" required>
</div>
<!-- /example:form -->
</main>
</body>
</html>
Need a key? Set up this browser example. For every field and parameter, see Email API reference.