Email Validation
validateEmailAddress
Validate an email address according to RFC 5322.
function validateEmailAddress ( email : string ) : boolean
Email address to validate
True if email is valid, false otherwise
Basic Usage
In Form Validation
import { validateEmailAddress } from '@proton/shared/lib/helpers/email' ;
validateEmailAddress ( '[email protected] ' ); // true
validateEmailAddress ( 'invalid@' ); // false
validateEmailAddress ( '@invalid.com' ); // false
validateEmailAddress ( '[email protected] ' ); // true
Features
Validates local part (before @)
Validates domain part (after @)
Supports quoted strings
Supports comments in local part
Follows RFC 5322 specification
validateLocalPart
Validate only the local part of an email address (before @).
function validateLocalPart ( localPart : string ) : boolean
Local part of email to validate
import { validateLocalPart } from '@proton/shared/lib/helpers/email' ;
validateLocalPart ( 'user' ); // true
validateLocalPart ( 'user+tag' ); // true
validateLocalPart ( 'user..name' ); // false (consecutive dots)
validateLocalPart ( '.user' ); // false (starts with dot)
Validation Rules
Cannot start or end with a dot
Cannot have consecutive dots
Supports alphanumeric and special characters: !#$%&ā*+/=?^_`{|}~.-
Supports quoted strings with escaped characters
Supports comments in parentheses
validateDomain
Validate the domain part of an email address (after @).
function validateDomain ( domain : string ) : boolean
import { validateDomain } from '@proton/shared/lib/helpers/email' ;
validateDomain ( 'example.com' ); // true
validateDomain ( 'sub.example.com' ); // true
validateDomain ( '[192.168.1.1]' ); // true (IP literal)
validateDomain ( 'xn--example-xya.com' ); // true (IDN)
validateDomain ( 'invalid' ); // false (no TLD)
Validation Rules
Maximum 255 characters
Requires at least two labels (e.g., example.com)
Supports subdomains
Supports IP address literals
Supports internationalized domain names (IDN)
Labels can contain alphanumeric, hyphens, and underscores
Cannot start or end with hyphen
Email Parsing
getEmailParts
Split an email address into local part and domain.
function getEmailParts (
email : string
) : [ localPart : string , domain : string ]
Tuple of [localPart, domain]
Basic Usage
With Plus Addressing
Invalid Email
import { getEmailParts } from '@proton/shared/lib/helpers/email' ;
const [ local , domain ] = getEmailParts ( '[email protected] ' );
// local: 'user'
// domain: 'example.com'
parseMailtoURL
Parse a mailto: URL to extract recipients and headers.
function parseMailtoURL (
mailtoURL : string ,
decode ?: boolean
) : { to : string [] }
Whether to decode URI components
Simple Mailto
Multiple Recipients
With Query Parameters
URL Encoded
Email Normalization
canonicalizeEmail
Normalize an email address using a specific canonicalization scheme.
function canonicalizeEmail (
email : string ,
scheme ?: CANONICALIZE_SCHEME
) : string
enum CANONICALIZE_SCHEME {
DEFAULT , // Lowercase only
PLUS , // Remove plus aliases
GMAIL , // Gmail rules (remove dots, plus aliases)
PROTON // Proton rules (remove dots, hyphens, underscores, plus aliases)
}
Email address to canonicalize
scheme
CANONICALIZE_SCHEME
default: "DEFAULT"
Canonicalization scheme to use
Default Scheme
Plus Addressing
Gmail Rules
Proton Rules
canonicalizeEmailByGuess
Automatically detect and apply the appropriate canonicalization scheme.
function canonicalizeEmailByGuess ( email : string ) : string
Email address to canonicalize
Supported Domains
Proton scheme:
protonmail.com
protonmail.ch
pm.me
proton.me
Gmail scheme:
gmail.com
googlemail.com
google.com
Plus scheme:
hotmail.com
hotmail.co.uk
hotmail.fr
outlook.com
yandex.ru
mail.ru
canonicalizeInternalEmail
Canonicalize a Proton email address.
function canonicalizeInternalEmail ( email : string ) : string
Email Utilities
addPlusAlias
Add a plus alias to an email address.
function addPlusAlias (
email ?: string ,
plus ?: string
) : string
removePlusAliasLocalPart
Remove plus alias from email local part.
function removePlusAliasLocalPart ( localPart ?: string ) : string
import { removePlusAliasLocalPart } from '@proton/shared/lib/helpers/email' ;
removePlusAliasLocalPart ( 'user+tag' );
// 'user'
removePlusAliasLocalPart ( 'user' );
// 'user'
isNoReplyEmail
Check if an email is a no-reply address.
function isNoReplyEmail ( email : string ) : boolean
Extract email from a user ID string (e.g., āName <[email protected] >ā).
function extractEmailFromUserID ( userID : string ) : string | undefined
Usage Examples
import { validateEmailAddress } from '@proton/shared/lib/helpers/email' ;
import { useState } from 'react' ;
function EmailForm () {
const [ email , setEmail ] = useState ( '' );
const [ error , setError ] = useState ( '' );
const handleSubmit = () => {
if ( ! validateEmailAddress ( email )) {
setError ( 'Please enter a valid email address' );
return ;
}
// Submit form
};
return (
< form onSubmit = { handleSubmit } >
< input
type = "email"
value = { email }
onChange = { ( e ) => {
setEmail ( e . target . value );
setError ( '' );
} }
/>
{ error && < div className = "error" > { error } </ div > }
< button type = "submit" > Submit </ button >
</ form >
);
}
Email Comparison
import { canonicalizeEmailByGuess } from '@proton/shared/lib/helpers/email' ;
function areEmailsEqual ( email1 : string , email2 : string ) : boolean {
const canonical1 = canonicalizeEmailByGuess ( email1 );
const canonical2 = canonicalizeEmailByGuess ( email2 );
return canonical1 === canonical2 ;
}
// Same inbox
areEmailsEqual (
'[email protected] ' ,
'[email protected] '
); // true
// Same inbox (dots ignored in Gmail)
areEmailsEqual (
'[email protected] ' ,
'[email protected] '
); // true
Domain Extraction
import { getEmailParts } from '@proton/shared/lib/helpers/email' ;
function getDomain ( email : string ) : string {
const [, domain ] = getEmailParts ( email );
return domain ;
}
const domain = getDomain ( '[email protected] ' );
// 'example.com'