Comprehensive validation library for Vue.js applications providing common validators with built-in error messages and customization options
87
Internationalization support for creating translatable validation error messages using i18n libraries.
Core function for creating translatable validation messages that integrate with internationalization libraries.
Creates a translatable version of the withMessage helper that works with i18n translation functions.
/**
* Creates translatable version of withMessage helper
* @param config - Configuration object for i18n integration
* @param config.t - Translation function from i18n library
* @param config.messagePath - Optional function to generate message paths
* @param config.messageParams - Optional function to generate message parameters
* @returns withI18nMessage function for creating translatable validators
*/
function createI18nMessage({
t,
messagePath?,
messageParams?
}): typeof withI18nMessage;The function returned by createI18nMessage that wraps validators with translatable messages.
/**
* Wraps validator with translatable message (returned by createI18nMessage)
* @param validator - Validator or ValidatorWrapper to enhance
* @param options - Optional configuration for message path/params
* @returns Enhanced validator with i18n message support
*/
function withI18nMessage<T extends (ValidationRule | ValidatorWrapper)>(
validator: T,
options?
): T;Usage Examples:
import { createI18nMessage, required, minLength, email } from "@vuelidate/validators";
// Example with Vue I18n
import { useI18n } from "vue-i18n";
const { t } = useI18n();
// Create the i18n message helper
const withI18nMessage = createI18nMessage({ t });
// Use with individual validators
const i18nRequired = withI18nMessage(required);
const i18nEmail = withI18nMessage(email);
const i18nMinLength = withI18nMessage(minLength(3));
// Validation rules with i18n messages
const validationRules = {
username: {
required: i18nRequired,
minLength: i18nMinLength
},
email: {
required: i18nRequired,
email: i18nEmail
}
};Interface definition for translation functions used with i18n libraries.
/**
* Translation function interface for i18n libraries
* @param path - Message key/path in translation files
* @param params - Parameters for message interpolation
* @returns Translated message string
*/
type TranslationFunction = (
path: string,
params: {
model: string,
property: string,
[key: string]: any
}
) => string;Factory function for generating consistent message paths for translation keys.
/**
* Factory for generating message paths for i18n
* @param params - Message properties from validator
* @returns String path for translation key
*/
type messagePathFactory = (params: MessageProps) => string;Factory function for generating parameters passed to translation functions.
/**
* Factory for generating message parameters
* @param params - Message parameters from validator
* @returns Processed parameters for translation
*/
type messageParamsFactory = (params: MessageParams) => MessageParams;Advanced Usage Examples:
import { createI18nMessage } from "@vuelidate/validators";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
// Advanced configuration with custom path and parameter factories
const withI18nMessage = createI18nMessage({
t,
// Custom message path generation
messagePath: (params) => {
const validator = params.$validator;
const property = params.$property;
return `validation.${validator}.${property}`;
},
// Custom parameter processing
messageParams: (params) => ({
...params,
fieldName: params.property.charAt(0).toUpperCase() + params.property.slice(1),
currentLength: params.model ? params.model.length : 0
})
});Complete example showing integration with Vue I18n library.
// i18n/messages.js
export const messages = {
en: {
validation: {
required: "The {property} field is required",
email: "The {property} field must be a valid email address",
minLength: "The {property} field must be at least {min} characters long",
maxLength: "The {property} field must not exceed {max} characters",
between: "The {property} field must be between {min} and {max}",
sameAs: "The {property} field must match {otherName}"
}
},
es: {
validation: {
required: "El campo {property} es requerido",
email: "El campo {property} debe ser un email válido",
minLength: "El campo {property} debe tener al menos {min} caracteres",
maxLength: "El campo {property} no debe exceder {max} caracteres",
between: "El campo {property} debe estar entre {min} y {max}",
sameAs: "El campo {property} debe coincidir con {otherName}"
}
},
fr: {
validation: {
required: "Le champ {property} est requis",
email: "Le champ {property} doit être une adresse email valide",
minLength: "Le champ {property} doit contenir au moins {min} caractères",
maxLength: "Le champ {property} ne doit pas dépasser {max} caractères",
between: "Le champ {property} doit être entre {min} et {max}",
sameAs: "Le champ {property} doit correspondre à {otherName}"
}
}
};
// validation.js
import { createI18nMessage, required, email, minLength, maxLength, between, sameAs } from "@vuelidate/validators";
import { useI18n } from "vue-i18n";
export function useValidationRules() {
const { t } = useI18n();
const withI18nMessage = createI18nMessage({
t,
messagePath: (params) => `validation.${params.$validator}`,
messageParams: (params) => ({
property: params.$property,
...params.$params
})
});
return {
required: withI18nMessage(required),
email: withI18nMessage(email),
minLength: (min) => withI18nMessage(minLength(min)),
maxLength: (max) => withI18nMessage(maxLength(max)),
between: (min, max) => withI18nMessage(between(min, max)),
sameAs: (equalTo, otherName) => withI18nMessage(sameAs(equalTo, otherName))
};
}
// component.vue
<template>
<form>
<input v-model="form.username" :class="{ error: $v.username.$error }" />
<span v-if="$v.username.$error">{{ $v.username.$errors[0].$message }}</span>
<input v-model="form.email" :class="{ error: $v.email.$error }" />
<span v-if="$v.email.$error">{{ $v.email.$errors[0].$message }}</span>
</form>
</template>
<script>
import { useVuelidate } from '@vuelidate/core';
import { useValidationRules } from './validation.js';
export default {
setup() {
const rules = useValidationRules();
const form = reactive({
username: '',
email: ''
});
const validationRules = {
username: {
required: rules.required,
minLength: rules.minLength(3)
},
email: {
required: rules.required,
email: rules.email
}
};
const $v = useVuelidate(validationRules, form);
return { form, $v };
}
};
</script>Integration example with React and i18next library.
// i18n/resources.js
export const resources = {
en: {
validation: {
required: "{{field}} is required",
email: "{{field}} must be a valid email address",
minLength: "{{field}} must be at least {{min}} characters long",
maxLength: "{{field}} must not exceed {{max}} characters"
}
},
de: {
validation: {
required: "{{field}} ist erforderlich",
email: "{{field}} muss eine gültige E-Mail-Adresse sein",
minLength: "{{field}} muss mindestens {{min}} Zeichen lang sein",
maxLength: "{{field}} darf {{max}} Zeichen nicht überschreiten"
}
}
};
// hooks/useValidation.js
import { createI18nMessage, required, email, minLength } from "@vuelidate/validators";
import { useTranslation } from "react-i18next";
export function useValidation() {
const { t } = useTranslation();
const withI18nMessage = createI18nMessage({
t: (key, params) => t(`validation.${key}`, params),
messageParams: (params) => ({
field: params.$property,
...params.$params
})
});
return {
required: withI18nMessage(required),
email: withI18nMessage(email),
minLength: (min) => withI18nMessage(minLength(min))
};
}Example with custom translation system.
// Custom translation function
function customTranslate(key, params) {
const translations = {
'validation.required': 'Field {property} is required',
'validation.email': 'Field {property} must be valid email',
'validation.minLength': 'Field {property} needs {min} characters minimum'
};
let message = translations[key] || key;
// Simple parameter replacement
Object.keys(params).forEach(param => {
message = message.replace(`{${param}}`, params[param]);
});
return message;
}
// Create i18n validator factory
const withI18nMessage = createI18nMessage({
t: customTranslate,
messagePath: (params) => `validation.${params.$validator}`,
messageParams: (params) => ({
property: params.$property.toLowerCase(),
...params.$params
})
});
// Usage
const validationRules = {
email: {
required: withI18nMessage(required),
email: withI18nMessage(email)
}
};// Recommended message key structure
const messageStructure = {
validation: {
// Core validators
required: "Field is required",
// Format validators
email: "Must be valid email",
url: "Must be valid URL",
// Length validators
minLength: "Must be at least {min} characters",
maxLength: "Must not exceed {max} characters",
// Value validators
minValue: "Must be at least {min}",
maxValue: "Must not exceed {max}",
between: "Must be between {min} and {max}",
// Conditional validators
requiredIf: "Required when {condition}",
sameAs: "Must match {otherName}"
}
};// Consistent parameter naming across languages
const withI18nMessage = createI18nMessage({
t,
messageParams: (params) => ({
// Normalize parameter names
field: params.$property,
value: params.$model,
min: params.$params.min,
max: params.$params.max,
otherField: params.$params.otherName
})
});// Fallback strategy for missing translations
const withI18nMessage = createI18nMessage({
t: (key, params) => {
const translated = i18n.t(key, params);
// Fallback to English if translation missing
if (translated === key) {
return i18n.t(key, { ...params, lng: 'en' });
}
return translated;
}
});Install with Tessl CLI
npx tessl i tessl/npm-vuelidate--validatorsdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10