Email Input
The email type renders a text input with automatic email format validation. It sets the HTML type="email" attribute for mobile keyboard optimisation, provides built-in format checking, and supports the confirm-email pattern for registration forms.
Minimal Example
{
"id": "email",
"type": "email",
"label": "Email Address",
"required": true,
"width": "half",
"binding": {
"source": "$json",
"path": "user.email"
}
}
Settings Reference
| Setting | Type | Default | Description |
|---|---|---|---|
placeholder | string | — | Ghost text shown when empty (e.g., you@example.com) |
maxLength | number | 254 | Maximum email length (RFC 5321 max is 254) |
autocomplete | string | email | HTML autocomplete attribute; "email" triggers browser suggestions |
toLower | boolean | true | Automatically convert input to lowercase on blur |
showIcon | boolean | true | Show envelope icon inside the input on the left |
allowedDomains | string[] | — | Restrict to specific domains (e.g., ["company.com"]) |
blockedDomains | string[] | — | Reject specific domains (e.g., disposable email providers) |
Built-in Format Validation
The email control automatically validates the format using the pattern /^[^\s@]+@[^\s@]+\.[^\s@]+$/. You do not need to add a pattern rule — it is always active when the field has a value. The format error message is: "Please enter a valid email address."
// This is sufficient — format validation is automatic:
{
"id": "email",
"type": "email",
"label": "Email",
"validation": {
"required": true
}
}
Domain Restrictions
To restrict email input to a specific set of domains (e.g., corporate onboarding forms):
{
"id": "work-email",
"type": "email",
"label": "Work Email",
"description": "Must be a company email address",
"settings": {
"allowedDomains": ["acme.com", "acme.co.uk"],
"placeholder": "yourname@acme.com"
},
"validation": {
"required": true
}
}
When a user enters someone@gmail.com, the error shown is: "Email must be from one of these domains: acme.com, acme.co.uk"
Confirm-Email Pattern
Registration and account-update forms often require the user to type their email twice. Implement this with two email fields and a customRule validator that compares values:
// Field 1: Primary email
{
"id": "email",
"type": "email",
"label": "Email Address",
"required": true,
"width": "half",
"order": 1,
"binding": {
"source": "$json",
"path": "registration.email"
}
},
// Field 2: Confirmation email
{
"id": "email-confirm",
"type": "email",
"label": "Confirm Email Address",
"required": true,
"width": "half",
"order": 2,
"settings": {
"autocomplete": "off"
},
"validation": {
"required": true,
"customRule": "matchesField",
"customRuleOptions": {
"fieldId": "email",
"message": "Email addresses do not match"
}
}
}
matchesField custom validator is provided by the Atlas Forms built-in validator library. It reads the current form values and compares the target field. Register it from @atlas-forms/validation-js if not automatically included.
Async Availability Check
For registration flows, check whether the email is already taken using an async custom validator:
// Register the validator in your app entry point
import { registerValidator } from '@atlas-forms/validation-js';
registerValidator('emailAvailable', async (value) => {
if (!value) return { valid: true };
const res = await fetch(`/api/auth/check-email?email=${encodeURIComponent(value)}`);
const data = await res.json();
return data.available
? { valid: true }
: { valid: false, message: 'This email is already registered' };
});
// Use in form schema
{
"id": "email",
"type": "email",
"label": "Email Address",
"validation": {
"required": true,
"customRule": "emailAvailable"
}
}
View Mode Display
In view and preview modes, the email is rendered as a mailto: hyperlink so reviewers can click to open their email client:
// Rendered output in view mode:
// <a href="mailto:user@example.com">user@example.com</a>