Skip to main content
Version: Next

ValidationChain

The validation chain contains all of the built-in validators, sanitizers and utility methods to fine tune the behaviour of the validation for a certain field or fields.

Validation chains are created by the check() functions, and they can be used in a few ways:

tip

If you're writing a function that accepts a ValidationChain, the TypeScript type can be imported using

import { ValidationChain } from 'express-validator';

Built-in validators

.custom()

custom(validator: (value, { req, location, path, pathValues }) => any): ValidationChain

Adds a custom validator function to the chain.

The field value will be valid if:

  • The custom validator returns truthy; or
  • The custom validator returns a promise that resolves.

If the custom validator returns falsy, a promise that rejects, or if the function throws, then the value will be considered invalid.

A common use case for .custom() is to verify that an e-mail address doesn't already exists. If it does, return an error:

app.post(
'/signup',
body('email').custom(async value => {
const existingUser = await Users.findUserByEmail(value);
if (existingUser) {
throw new Error('E-mail already in use');
}
}),
(req, res) => {
// Handle request
},
);

If the field was selected using wildcards or globstars, you can access the values they matched by using the pathValues property. This is useful if you want to use some other property of the same object in your validation:

app.post(
'/purchase',
[
body('products.*.quantity').custom((quantity, { req, pathValues }) => {
const index = Number(pathValues[0]);
const { id } = req.body.products[index];

if (getProductStock(id) < quantity) {
throw new Error(`There's not enough of product ${id} in stock`);
}
}),
],
(req, res) => {
// Handle request
},
);

.exists()

exists(options?: {
values?: 'undefined' | 'null' | 'falsy',
checkNull?: boolean,
checkFalsy?: boolean
}): ValidationChain

Adds a validator to check if the field exists.

Which values are considered existent depends on options.values. By default, it's set to undefined:

options.valuesBehavior
undefinedundefined values don't exist
nullundefined and null values don't exist
falsyFalsy values (empty strings, 0, false, null and undefined values don't exist

options.checkNull and options.checkFalsy are deprecated options. They are aliases to setting options.values to null and falsy, respectively.

note

Using .exists() is only necessary if you aren't adding any other validator or sanitizer.

.isArray()

isArray(options?: { min?: number; max?: number }): ValidationChain

Adds a validator to check that a value is an array. This is analogous to the JavaScript function Array.isArray(value).

You can also check that the array's length is greater than or equal to options.min and/or that it's less than or equal to options.max.

// Verifies that the friends list is an array
body('friends').isArray();

// Verifies that ingredients is an array with length >= 0
body('ingredients').isArray({ min: 0 });

// Verifies that team_members is an array with length >= 0 and <= 10
check('team_members').isArray({ min: 0, max: 10 });

.isObject()

isObject(options?: { strict?: boolean }): ValidationChain

Adds a validator to check that a value is an object. For example, {}, { foo: 'bar' } and new MyCustomClass() would all pass this validator.

If the strict option is set to false, then this validator works analogous to typeof value === 'object' in pure JavaScript, where both arrays and the null value are considered objects.

.isString()

isString(): ValidationChain

Adds a validator to check that a value is a string. This is analogous to a typeof value === 'string' in pure JavaScript.

.isULID()

isULID(): ValidationChain

Adds a validator to check that a value is an ULID.

.notEmpty()

notEmpty(): ValidationChain

Adds a validator to check that a value is a string that's not empty. This is analogous to .not().isEmpty().

Standard validators

info

Please check the documentation on standard validators here.

contains()

contains(elem: any, options?: {
ignoreCase?: boolean;
minOccurrences?: number;
}): ValidationChain

equals()

equals(comparison: string): ValidationChain

isAbaRouting()

isAbaRouting(): ValidationChain

isAfter()

isAfter(dateOrOptions?: string | {
comparisonDate?: string;
}): ValidationChain

isAlpha()

isAlpha(locale?: AlphaLocale, options?: {
ignore?: string | string[] | RegExp;
}): ValidationChain
Possible values of AlphaLocale
  • 'ar'
  • 'ar-AE'
  • 'ar-BH'
  • 'ar-DZ'
  • 'ar-EG'
  • 'ar-IQ'
  • 'ar-JO'
  • 'ar-KW'
  • 'ar-LB'
  • 'ar-LY'
  • 'ar-MA'
  • 'ar-QA'
  • 'ar-QM'
  • 'ar-SA'
  • 'ar-SD'
  • 'ar-SY'
  • 'ar-TN'
  • 'ar-YE'
  • 'az-AZ'
  • 'bg-BG'
  • 'bn-BD'
  • 'cs-CZ'
  • 'da-DK'
  • 'de-DE'
  • 'el-GR'
  • 'en-AU'
  • 'en-GB'
  • 'en-HK'
  • 'en-IN'
  • 'en-NZ'
  • 'en-US'
  • 'en-ZA'
  • 'en-ZM'
  • 'es-ES'
  • 'eo'
  • 'fa-AF'
  • 'fa-IR'
  • 'fi-FI'
  • 'fr-FR'
  • 'he'
  • 'hi-IN'
  • 'hu-HU'
  • 'id-ID'
  • 'it-IT'
  • 'ja-JP'
  • 'kk-KZ'
  • 'ko-KR'
  • 'ku-IQ'
  • 'nb-NO'
  • 'nl-NL'
  • 'nn-NO'
  • 'pl-PL'
  • 'pt-BR'
  • 'pt-PT'
  • 'ru-RU'
  • 'si-LK'
  • 'sk-SK'
  • 'sl-SI'
  • 'sr-RS'
  • 'sr-RS@latin'
  • 'sv-SE'
  • 'th-TH'
  • 'tr-TR'
  • 'uk-UA'
  • 'vi-VN'

isAlphanumeric()

isAlphanumeric(locale?: AlphanumericLocale, options?: {
ignore?: string | RegExp;
}): ValidationChain
Possible values of AlphanumericLocale
  • 'ar'
  • 'ar-AE'
  • 'ar-BH'
  • 'ar-DZ'
  • 'ar-EG'
  • 'ar-IQ'
  • 'ar-JO'
  • 'ar-KW'
  • 'ar-LB'
  • 'ar-LY'
  • 'ar-MA'
  • 'ar-QA'
  • 'ar-QM'
  • 'ar-SA'
  • 'ar-SD'
  • 'ar-SY'
  • 'ar-TN'
  • 'ar-YE'
  • 'az-AZ'
  • 'bg-BG'
  • 'bn-BD'
  • 'cs-CZ'
  • 'da-DK'
  • 'de-DE'
  • 'el-GR'
  • 'en-AU'
  • 'en-GB'
  • 'en-HK'
  • 'en-IN'
  • 'en-NZ'
  • 'en-US'
  • 'en-ZA'
  • 'en-ZM'
  • 'es-ES'
  • 'eo'
  • 'fa-AF'
  • 'fa-IR'
  • 'fi-FI'
  • 'fr-FR'
  • 'fr-BE'
  • 'he'
  • 'hi-IN'
  • 'hu-HU'
  • 'it-IT'
  • 'id-ID'
  • 'ja-JP'
  • 'kk-KZ'
  • 'ko-KR'
  • 'ku-IQ'
  • 'nb-NO'
  • 'nl-BE'
  • 'nl-NL'
  • 'nn-NO'
  • 'pl-PL'
  • 'pt-BR'
  • 'pt-PT'
  • 'ru-RU'
  • 'si-LK'
  • 'sk-SK'
  • 'sl-SI'
  • 'sr-RS'
  • 'sr-RS@latin'
  • 'sv-SE'
  • 'th-TH'
  • 'tr-TR'
  • 'uk-UA'
  • 'vi-VN'

isAscii()

isAscii(): ValidationChain

isBase32()

isBase32(options?: {
crockford?: boolean;
}): ValidationChain

isBase58()

isBase58(): ValidationChain

isBase64()

isBase64(options?: {
urlSafe?: boolean;
}): ValidationChain

isBefore()

isBefore(date?: string): ValidationChain

isBIC()

isBIC(): ValidationChain

isBoolean()

isBoolean(options?: {
strict?: boolean;
loose?: boolean;
}): ValidationChain

isBtcAddress()

isBtcAddress(): ValidationChain

isByteLength()

isByteLength(options: {
min?: number;
max?: number;
lt?: number;
gt?: number;
}): ValidationChain

isCreditCard()

isCreditCard(options?: {
provider?: 'amex' | 'dinersclub' | 'discover' | 'jcb' | 'mastercard' | 'unionpay' | 'visa';
}): ValidationChain

isCurrency()

isCurrency(options?: {
symbol?: string;
require_symbol?: boolean;
allow_space_after_symbol?: boolean;
symbol_after_digits?: boolean;
allow_negatives?: boolean;
parens_for_negatives?: boolean;
negative_sign_before_digits?: boolean;
negative_sign_after_digits?: boolean;
allow_negative_sign_placeholder?: boolean;
thousands_separator?: string;
decimal_separator?: string;
allow_decimal?: boolean;
require_decimal?: boolean;
digits_after_decimal?: number[];
allow_space_after_digits?: boolean;
}): ValidationChain

isDataURI()

isDataURI(): ValidationChain

isDate()

isDate(options?: {
format?: string;
delimiters?: string[];
strictMode?: boolean;
}): ValidationChain

isDecimal()

isDecimal(options?: {
decimal_digits?: string;
force_decimal?: boolean;
locale?: AlphanumericLocale;
blacklisted_chars?: string;
}): ValidationChain

isDivisibleBy()

isDivisibleBy(number: number): ValidationChain

isEAN()

isEAN(): ValidationChain

isEmail()

isEmail(options?: {
allow_display_name?: boolean;
allow_underscores?: boolean;
allow_utf8_local_part?: boolean;
require_tld?: boolean;
ignore_max_length?: boolean;
allow_ip_domain?: boolean;
domain_specific_validation?: boolean;
blacklisted_chars?: string;
host_blacklist?: string[];
host_whitelist?: string[];
}): ValidationChain

isEmpty()

isEmpty(options?: {
ignore_whitespace: boolean;
}): ValidationChain

isEthereumAddress()

isEthereumAddress(): ValidationChain

isFQDN()

isFQDN(options?: {
require_tld?: boolean;
allow_underscores?: boolean;
allow_trailing_dot?: boolean;
allow_numeric_tld?: boolean;
allow_wildcard?: boolean;
ignore_max_length?: boolean;
}): ValidationChain

isFloat()

isFloat(options?: {
min?: number;
max?: number;
lt?: number;
gt?: number;
locale?: AlphanumericLocale;
}): ValidationChain

isFreightContainerID()

isFreightContainerID(): ValidationChain

isFullWidth()

isFullWidth(): ValidationChain

isHalfWidth()

isHalfWidth(): ValidationChain

isHash()

isHash(algorithm: HashAlgorithm): ValidationChain
Possible values of HashAlgorithm
  • 'md4'
  • 'md5'
  • 'sha1'
  • 'sha256'
  • 'sha384'
  • 'sha512'
  • 'ripemd128'
  • 'ripemd160'
  • 'tiger128'
  • 'tiger160'
  • 'tiger192'
  • 'crc32'
  • 'crc32b'

isHexColor()

isHexColor(): ValidationChain

isHexadecimal()

isHexadecimal(): ValidationChain

isHSL()

isHSL(): ValidationChain

isIBAN()

isIBAN(options?: {
whitelist?: readonly IBANCode[];
blacklist?: readonly IBANCode[];
}): ValidationChain

isIdentityCard()

isIdentityCard(locale?: IdentityCardLocale): ValidationChain
Possible values of IdentityCardLocale
  • 'any'
  • 'ar-LY'
  • 'ar-TN'
  • 'ES'
  • 'FI'
  • 'he-IL'
  • 'hk-HK'
  • 'IN'
  • 'IT'
  • 'IR'
  • 'MZ'
  • 'NO'
  • 'PL'
  • 'TH'
  • 'zh-CN'
  • 'zh-TW'

isIMEI()

isIMEI(options?: {
allow_hyphens?: boolean;
}): ValidationChain

isIP()

isIP(version?: 4 | 6): ValidationChain

isIPRange()

isIPRange(version?: 4 | 6): ValidationChain

isISBN()

isISBN(versionOrOptions?: number | {
version?: '10' | '13';
}): ValidationChain

isISSN()

isISSN(options?: {
case_sensitive?: boolean;
require_hyphen?: boolean;
}): ValidationChain

isISIN()

isISIN(): ValidationChain

isISO6346()

isISO6346(): ValidationChain

isISO6391()

isISO6391(): ValidationChain

isISO8601()

isISO8601(options?: {
strict?: boolean;
strictSeparator?: boolean;
}): ValidationChain

isISO31661Alpha2()

isISO31661Alpha2(): ValidationChain

isISO31661Alpha3()

isISO31661Alpha3(): ValidationChain

isISO4217()

isISO4217(): ValidationChain

isISRC()

isISRC(): ValidationChain

isIn()

isIn(values: readonly any[]): ValidationChain

isInt()

isInt(options?: {
min?: number;
max?: number;
lt?: number;
gt?: number;
allow_leading_zeroes?: boolean;
}): ValidationChain

isJSON()

isJSON(options?: {
allow_primitives?: boolean;
}): ValidationChain

isJWT()

isJWT(): ValidationChain

isLatLong()

isLatLong(options?: {
checkDMS?: boolean;
}): ValidationChain

isLength()

isLength(options: {
min?: number;
max?: number;
}): ValidationChain

isLicensePlate()

isLicensePlate(locale: IsLicensePlateLocale): ValidationChain
Possible values of IsLicensePlateLocale
  • 'cs-CZ'
  • 'de-DE'
  • 'de-LI'
  • 'en-NI'
  • 'en-PK'
  • 'es-AR'
  • 'fi-FI'
  • 'hu-HU'
  • 'pt-BR'
  • 'pt-PT'
  • 'sq-AL'
  • 'sv-SE'
  • 'any'

isLocale()

isLocale(): ValidationChain

isLowercase()

isLowercase(): ValidationChain

isLuhnNumber()

isLuhnNumber(): ValidationChain

isMagnetURI()

isMagnetURI(): ValidationChain

isMailtoURI()

isMailtoURI(options?: {
allow_display_name?: boolean;
allow_underscores?: boolean;
allow_utf8_local_part?: boolean;
require_tld?: boolean;
ignore_max_length?: boolean;
allow_ip_domain?: boolean;
domain_specific_validation?: boolean;
blacklisted_chars?: string;
host_blacklist?: string[];
host_whitelist?: string[];
}): ValidationChain

isMACAddress()

isMACAddress(options?: {
no_separators?: boolean;
no_colons?: boolean;
eui?: '48' | '64';
}): ValidationChain

isMD5()

isMD5(): ValidationChain

isMimeType()

isMimeType(): ValidationChain

isMobilePhone()

isMobilePhone(locale: MobilePhoneLocale | readonly Options.MobilePhoneLocale[], options?: {
strictMode?: boolean;
}): ValidationChain
Possible values of MobilePhoneLocale
  • 'any'
  • 'am-AM'
  • 'ar-AE'
  • 'ar-BH'
  • 'ar-DZ'
  • 'ar-EG'
  • 'ar-EH'
  • 'ar-IQ'
  • 'ar-JO'
  • 'ar-KW'
  • 'ar-LB'
  • 'ar-LY'
  • 'ar-MA'
  • 'ar-OM'
  • 'ar-PS'
  • 'ar-SA'
  • 'ar-SD'
  • 'ar-SY'
  • 'ar-TN'
  • 'ar-YE'
  • 'az-AZ'
  • 'be-BY'
  • 'bg-BG'
  • 'bn-BD'
  • 'bs-BA'
  • 'cs-CZ'
  • 'de-AT'
  • 'de-CH'
  • 'de-DE'
  • 'de-LU'
  • 'da-DK'
  • 'dv-MV'
  • 'dz-BT'
  • 'el-CY'
  • 'el-GR'
  • 'en-AG'
  • 'en-AI'
  • 'en-AU'
  • 'en-BM'
  • 'en-BS'
  • 'en-BW'
  • 'en-CA'
  • 'en-GB'
  • 'en-GG'
  • 'en-GH'
  • 'en-GY'
  • 'en-HK'
  • 'en-HN'
  • 'en-IE'
  • 'en-IN'
  • 'en-JM'
  • 'en-KE'
  • 'en-KI'
  • 'en-KN'
  • 'en-LS'
  • 'en-MT'
  • 'en-MU'
  • 'en-MW'
  • 'en-NA'
  • 'en-NG'
  • 'en-NZ'
  • 'en-PG'
  • 'en-PH'
  • 'en-PK'
  • 'en-RW'
  • 'en-SG'
  • 'en-SL'
  • 'en-SS'
  • 'en-TZ'
  • 'en-UG'
  • 'en-US'
  • 'en-ZA'
  • 'en-ZM'
  • 'en-ZW'
  • 'es-AR'
  • 'es-BO'
  • 'es-CL'
  • 'es-CO'
  • 'es-CR'
  • 'es-CU'
  • 'es-DO'
  • 'es-EC'
  • 'es-ES'
  • 'es-HN'
  • 'es-MX'
  • 'es-NI'
  • 'es-PA'
  • 'es-PE'
  • 'es-PY'
  • 'es-SV'
  • 'es-UY'
  • 'es-VE'
  • 'et-EE'
  • 'fa-AF'
  • 'fa-IR'
  • 'fi-FI'
  • 'fj-FJ'
  • 'fo-FO'
  • 'fr-BE'
  • 'fr-BF'
  • 'fr-BJ'
  • 'fr-CD'
  • 'fr-CF'
  • 'fr-CH'
  • 'fr-CM'
  • 'fr-FR'
  • 'fr-GF'
  • 'fr-GP'
  • 'fr-MQ'
  • 'fr-PF'
  • 'fr-RE'
  • 'fr-WF'
  • 'ga-IE'
  • 'he-IL'
  • 'hu-HU'
  • 'id-ID'
  • 'ir-IR'
  • 'it-CH'
  • 'it-IT'
  • 'it-SM'
  • 'ja-JP'
  • 'ka-GE'
  • 'kk-KZ'
  • 'kl-GL'
  • 'ko-KR'
  • 'ky-KG'
  • 'lt-LT'
  • 'lv-LV'
  • 'mg-MG'
  • 'mn-MN'
  • 'ms-MY'
  • 'my-MM'
  • 'mz-MZ'
  • 'nb-NO'
  • 'nl-AW'
  • 'nl-BE'
  • 'nl-NL'
  • 'ne-NP'
  • 'nn-NO'
  • 'pl-PL'
  • 'pt-AO'
  • 'pt-BR'
  • 'pt-PT'
  • 'ro-MD'
  • 'ro-RO'
  • 'ru-RU'
  • 'si-LK'
  • 'sk-SK'
  • 'sl-SI'
  • 'so-SO'
  • 'sq-AL'
  • 'sr-RS'
  • 'sv-SE'
  • 'tg-TJ'
  • 'th-TH'
  • 'tk-TM'
  • 'tr-TR'
  • 'uk-UA'
  • 'uz-Uz'
  • 'vi-VN'
  • 'zh-CN'
  • 'zh-HK'
  • 'zh-TW'

isMongoId()

isMongoId(): ValidationChain

isMultibyte()

isMultibyte(): ValidationChain

isNumeric()

isNumeric(options?: {
no_symbols: boolean;
locale?: AlphanumericLocale;
}): ValidationChain

isOctal()

isOctal(): ValidationChain

isPassportNumber()

isPassportNumber(countryCode?: PassportCountryCode): ValidationChain
Possible values of PassportCountryCode
  • 'AM'
  • 'AR'
  • 'AT'
  • 'AU'
  • 'AZ'
  • 'BE'
  • 'BG'
  • 'BY'
  • 'BR'
  • 'CA'
  • 'CH'
  • 'CN'
  • 'CY'
  • 'CZ'
  • 'DE'
  • 'DK'
  • 'DZ'
  • 'EE'
  • 'ES'
  • 'FI'
  • 'FR'
  • 'GB'
  • 'GR'
  • 'HR'
  • 'HU'
  • 'ID'
  • 'IE'
  • 'IN'
  • 'IR'
  • 'IS'
  • 'IT'
  • 'JM'
  • 'JP'
  • 'KR'
  • 'KZ'
  • 'LI'
  • 'LT'
  • 'LU'
  • 'LV'
  • 'LY'
  • 'MT'
  • 'MY'
  • 'MZ'
  • 'NL'
  • 'NZ'
  • 'PH'
  • 'PK'
  • 'PL'
  • 'PO'
  • 'PT'
  • 'RO'
  • 'RU'
  • 'SE'
  • 'SL'
  • 'SK'
  • 'TH'
  • 'TR'
  • 'UA'
  • 'US'
  • 'ZA'

isPort()

isPort(): ValidationChain

isPostalCode()

isPostalCode(locale: PostalCodeLocale): ValidationChain
Possible values of PostalCodeLocale
  • 'any'
  • 'AD'
  • 'AT'
  • 'AU'
  • 'AZ'
  • 'BA'
  • 'BE'
  • 'BG'
  • 'BR'
  • 'BY'
  • 'CA'
  • 'CH'
  • 'CN'
  • 'CZ'
  • 'DE'
  • 'DK'
  • 'DO'
  • 'DZ'
  • 'EE'
  • 'ES'
  • 'FI'
  • 'FR'
  • 'GB'
  • 'GR'
  • 'HR'
  • 'HT'
  • 'HU'
  • 'ID'
  • 'IL'
  • 'IN'
  • 'IR'
  • 'IS'
  • 'IT'
  • 'JP'
  • 'KE'
  • 'KR'
  • 'LI'
  • 'LK'
  • 'LT'
  • 'LU'
  • 'LV'
  • 'MT'
  • 'MX'
  • 'MY'
  • 'NL'
  • 'NO'
  • 'NP'
  • 'NZ'
  • 'PL'
  • 'PR'
  • 'PT'
  • 'RO'
  • 'RU'
  • 'SA'
  • 'SE'
  • 'SG'
  • 'SI'
  • 'SK'
  • 'TH'
  • 'TN'
  • 'TW'
  • 'UA'
  • 'US'
  • 'ZA'
  • 'ZM'

isRgbColor()

isRgbColor(includePercentValues?: boolean): ValidationChain

isRFC3339()

isRFC3339(): ValidationChain

isSemVer()

isSemVer(): ValidationChain

isSlug()

isSlug(): ValidationChain

isStrongPassword()

isStrongPassword(options?: {
minLength?: number;
minLowercase?: number;
minUppercase?: number;
minNumbers?: number;
minSymbols?: number;
returnScore?: boolean;
pointsPerUnique?: number;
pointsPerRepeat?: number;
pointsForContainingLower?: number;
pointsForContainingUpper?: number;
pointsForContainingNumber?: number;
pointsForContainingSymbol?: number;
}): ValidationChain

isSurrogatePair()

isSurrogatePair(): ValidationChain

isTaxID()

isTaxID(locale: TaxIDLocale): ValidationChain
Possible values of TaxIDLocale
  • 'bg-BG'
  • 'cs-CZ'
  • 'de-AT'
  • 'de-DE'
  • 'dk-DK'
  • 'el-CY'
  • 'el-GR'
  • 'en-CA'
  • 'en-GB'
  • 'en-IE'
  • 'en-US'
  • 'es-AR'
  • 'es-ES'
  • 'et-EE'
  • 'fi-FI'
  • 'fr-BE'
  • 'fr-FR'
  • 'fr-LU'
  • 'hr-HR'
  • 'hu-HU'
  • 'it-IT'
  • 'lb-LU'
  • 'lt-LT'
  • 'lv-LV'
  • 'mt-MT'
  • 'nl-BE'
  • 'nl-NL'
  • 'pl-PL'
  • 'pt-BR'
  • 'pt-PT'
  • 'ro-RO'
  • 'sk-SK'
  • 'sl-SI'
  • 'sv-SE'
  • 'uk-UA'

isTime()

isTime(options: {
hourFormat?: 'hour24' | 'hour12';
mode?: 'default' | 'withSeconds';
}): ValidationChain

isURL()

isURL(options?: {
require_tld?: boolean;
allow_underscores?: boolean;
allow_trailing_dot?: boolean;
allow_numeric_tld?: boolean;
allow_wildcard?: boolean;
ignore_max_length?: boolean;
protocols?: URLProtocol[];
require_protocol?: boolean;
require_host?: boolean;
require_port?: boolean;
require_valid_protocol?: boolean;
host_whitelist?: (string | RegExp)[];
host_blacklist?: (string | RegExp)[];
allow_protocol_relative_urls?: boolean;
disallow_auth?: boolean;
validate_length?: boolean;
allow_fragments?: boolean;
allow_query_components?: boolean;
}): ValidationChain

isUUID()

isUUID(version?: UUIDVersion): ValidationChain
Possible values of UUIDVersion
  • 1
  • 2
  • 3
  • 4
  • 5
  • 7
  • '1'
  • '2'
  • '3'
  • '4'
  • '5'
  • '7'
  • 'all'

isUppercase()

isUppercase(): ValidationChain

isVariableWidth()

isVariableWidth(): ValidationChain

isVAT()

isVAT(countryCode: VATCountryCode): ValidationChain
Possible values of VATCountryCode
  • 'GB'
  • 'IT'
  • 'NL'
  • 'AT'
  • 'BE'
  • 'BG'
  • 'HR'
  • 'CU'
  • 'CY'
  • 'CZ'
  • 'DK'
  • 'EE'
  • 'FI'
  • 'FR'
  • 'DE'
  • 'EL'
  • 'HU'
  • 'IE'
  • 'LV'
  • 'LT'
  • 'LU'
  • 'MT'
  • 'PL'
  • 'PT'
  • 'RO'
  • 'SK'
  • 'SI'
  • 'ES'
  • 'SE'
  • 'AL'
  • 'MK'
  • 'AU'
  • 'BY'
  • 'CA'
  • 'IS'
  • 'IN'
  • 'ID'
  • 'IL'
  • 'KZ'
  • 'NZ'
  • 'NG'
  • 'NO'
  • 'PH'
  • 'RU'
  • 'SM'
  • 'SA'
  • 'RS'
  • 'CH'
  • 'TR'
  • 'UA'
  • 'UZ'
  • 'AR'
  • 'BO'
  • 'BR'
  • 'CL'
  • 'CO'
  • 'CR'
  • 'EC'
  • 'SV'
  • 'GT'
  • 'HN'
  • 'MX'
  • 'NI'
  • 'PA'
  • 'PY'
  • 'PE'
  • 'DO'
  • 'UY'
  • 'VE'

isWhitelisted()

isWhitelisted(chars: string | readonly string[]): ValidationChain

matches()

matches(pattern: RegExp | string, modifiers?: string): ValidationChain

Built-in sanitizers

.customSanitizer()

customSanitizer(sanitizer: (value, { req, location, path, pathValues }) => any): ValidationChain

Adds a custom sanitizer function to the chain. The value returned by the function will become the new value of the field.

app.post('/object/:id', param('id').customSanitizer((value, { req }) => {
// In this app, users have MongoDB style object IDs, everything else, numbers
return req.query.type === 'user' ? ObjectId(value) : Number(value);
})), (req, res) => {
// Handle request
});

.default()

default(defaultValue: any): ValidationChain

Replaces the value of the field if it's either an empty string, null, undefined, or NaN.

app.post('/', body('username').default('foo'), (req, res, next) => {
// 'bar' => 'bar'
// '' => 'foo'
// undefined => 'foo'
// null => 'foo'
// NaN => 'foo'
});

.replace()

replace(valuesFrom: any[], valueTo: any): ValidationChain

Replaces the value of the field with valueTo whenever the current value is in valuesFrom.

app.post('/', body('username').replace(['bar', 'BAR'], 'foo'), (req, res, next) => {
// 'bar_' => 'bar_'
// 'bar' => 'foo'
// 'BAR' => 'foo'
console.log(req.body.username);
});

.toArray()

toArray(): ValidationChain

Transforms the value to an array. If it already is one, nothing is done. undefined values become empty arrays.

.toLowerCase()

toLowerCase(): ValidationChain

Converts the value to lower case. If not a string, does nothing.

.toUpperCase()

toUpperCase(): ValidationChain

Converts the value to upper case. If not a string, does nothing.

Standard sanitizers

info

Please check the documentation on standard sanitizers here.

blacklist()

blacklist(chars: string): ValidationChain

escape()

escape(): ValidationChain

unescape()

unescape(): ValidationChain

ltrim()

ltrim(chars?: string): ValidationChain

normalizeEmail()

normalizeEmail(options?: {
all_lowercase?: boolean;
gmail_lowercase?: boolean;
gmail_remove_dots?: boolean;
gmail_remove_subaddress?: boolean;
gmail_convert_googlemaildotcom?: boolean;
outlookdotcom_lowercase?: boolean;
outlookdotcom_remove_subaddress?: boolean;
yahoo_lowercase?: boolean;
yahoo_remove_subaddress?: boolean;
icloud_lowercase?: boolean;
icloud_remove_subaddress?: boolean;
}): ValidationChain

rtrim()

rtrim(chars?: string): ValidationChain

stripLow()

stripLow(keep_new_lines?: boolean): ValidationChain

toBoolean()

toBoolean(strict?: boolean): ValidationChain

toDate()

toDate(): ValidationChain

toFloat()

toFloat(): ValidationChain

toInt()

toInt(radix?: number): ValidationChain

trim()

trim(chars?: string): ValidationChain

whitelist()

whitelist(chars: string): ValidationChain

Modifiers

.bail()

bail(options?: { level: 'chain' | 'request' }): ValidationChain

Parameters:

NameDescription
options.levelThe level at which the validation chain should be stopped. Defaults to chain.

Stops running the validation chain if any of the previous validators failed.

This is useful to prevent a custom validator that touches a database or external API from running when you know it will fail.

.bail() can be used multiple times in the same validation chain if desired:

body('username')
.isEmail()
// If not an email, stop here
.bail()
.custom(checkDenylistDomain)
// If domain is not allowed, don't go check if it already exists
.bail()
.custom(checkEmailExists);

If the level option is set to request, then also no further validation chains will run on the current request. For example:

app.get(
'/search',
query('query').notEmpty().bail({ level: 'request' }),
// If `query` is empty, then the following validation chains won't run:
query('query_type').isIn(['user', 'posts']),
query('num_results').isInt(),
(req, res) => {
// Handle request
},
);
caution

Functions such as oneOf() and checkExact() can become slower when using request-level bail, since validation chains that would normally run in parallel need to run in sequence.

.if()

if(condition: CustomValidator | ContextRunner): ValidationChain

Adds a condition on whether the validation chain should continue running on a field or not.

The condition may be either a custom validator or a ContextRunner instance.

body('newPassword')
// Only validate if the old password has been provided
.if((value, { req }) => req.body.oldPassword)
// Or, use a validation chain instead
.if(body('oldPassword').notEmpty())
// The length of the new password will only be checked if `oldPassword` is provided.
.isLength({ min: 6 });

.not()

not(): ValidationChain

Negates the result of the next validator in the chain.

check('weekday').not().isIn(['sunday', 'saturday']);

.optional()

optional(options?: boolean | {
values?: 'undefined' | 'null' | 'falsy',
nullable?: boolean,
checkFalsy?: boolean,
}): ValidationChain

Marks the current validation chain as optional. An optional field skips validation depending on its value, instead of failing it.

Which values are considered optional depends on options.values. By default, it's set to undefined:

options.valuesBehavior
undefinedundefined values are optional
nullundefined and null values are optional
falsyFalsy values (empty strings, 0, false, null and undefined values are optional

options.nullable and options.checkFalsy are deprecated options. They are aliases to setting options.values to null or falsy.

If options is false, then the field won't be optional.

info

Unlike validators and sanitizers, .optional() is not positional: it'll affect how values are interpreted, no matter where it happens in the chain.

For example, there are no differences between this:

body('json_string').isLength({ max: 100 }).isJSON().optional().

and this:

body('json_string').optional().isLength({ max: 100 }).isJSON().

.hide()

hide(hiddenValue?: string): ValidationChain

Hide the field's value in errors returned by validationResult(). If the value is confidential information (such as api key), you might want to call this method to prevent exposing it. If hiddenValue is set, it's set as the value in the errors for this field.

NameDescription
hiddenValueString to replace field's value with.
// Omits the value in the errors
query('api_key').custom(isValidKey).hide();

// Replaces the value in the errors with '*****'
query('api_key').custom(isValidKey).hide('*****');

.withMessage()

withMessage(message: any): ValidationChain

Sets the error message used by the previous validator.