0
# Internationalization
1
2
Internationalization support for creating translatable validation error messages using i18n libraries.
3
4
## Capabilities
5
6
### I18n Message Creation
7
8
Core function for creating translatable validation messages that integrate with internationalization libraries.
9
10
#### Create I18n Message Function
11
12
Creates a translatable version of the withMessage helper that works with i18n translation functions.
13
14
```javascript { .api }
15
/**
16
* Creates translatable version of withMessage helper
17
* @param config - Configuration object for i18n integration
18
* @param config.t - Translation function from i18n library
19
* @param config.messagePath - Optional function to generate message paths
20
* @param config.messageParams - Optional function to generate message parameters
21
* @returns withI18nMessage function for creating translatable validators
22
*/
23
function createI18nMessage({
24
t,
25
messagePath?,
26
messageParams?
27
}): typeof withI18nMessage;
28
```
29
30
#### With I18n Message Function
31
32
The function returned by `createI18nMessage` that wraps validators with translatable messages.
33
34
```javascript { .api }
35
/**
36
* Wraps validator with translatable message (returned by createI18nMessage)
37
* @param validator - Validator or ValidatorWrapper to enhance
38
* @param options - Optional configuration for message path/params
39
* @returns Enhanced validator with i18n message support
40
*/
41
function withI18nMessage<T extends (ValidationRule | ValidatorWrapper)>(
42
validator: T,
43
options?
44
): T;
45
```
46
47
**Usage Examples:**
48
49
```javascript
50
import { createI18nMessage, required, minLength, email } from "@vuelidate/validators";
51
52
// Example with Vue I18n
53
import { useI18n } from "vue-i18n";
54
55
const { t } = useI18n();
56
57
// Create the i18n message helper
58
const withI18nMessage = createI18nMessage({ t });
59
60
// Use with individual validators
61
const i18nRequired = withI18nMessage(required);
62
const i18nEmail = withI18nMessage(email);
63
const i18nMinLength = withI18nMessage(minLength(3));
64
65
// Validation rules with i18n messages
66
const validationRules = {
67
username: {
68
required: i18nRequired,
69
minLength: i18nMinLength
70
},
71
email: {
72
required: i18nRequired,
73
email: i18nEmail
74
}
75
};
76
```
77
78
### Translation Function Integration
79
80
#### Translation Function Type
81
82
Interface definition for translation functions used with i18n libraries.
83
84
```javascript { .api }
85
/**
86
* Translation function interface for i18n libraries
87
* @param path - Message key/path in translation files
88
* @param params - Parameters for message interpolation
89
* @returns Translated message string
90
*/
91
type TranslationFunction = (
92
path: string,
93
params: {
94
model: string,
95
property: string,
96
[key: string]: any
97
}
98
) => string;
99
```
100
101
#### Message Path Factory
102
103
Factory function for generating consistent message paths for translation keys.
104
105
```javascript { .api }
106
/**
107
* Factory for generating message paths for i18n
108
* @param params - Message properties from validator
109
* @returns String path for translation key
110
*/
111
type messagePathFactory = (params: MessageProps) => string;
112
```
113
114
#### Message Parameters Factory
115
116
Factory function for generating parameters passed to translation functions.
117
118
```javascript { .api }
119
/**
120
* Factory for generating message parameters
121
* @param params - Message parameters from validator
122
* @returns Processed parameters for translation
123
*/
124
type messageParamsFactory = (params: MessageParams) => MessageParams;
125
```
126
127
**Advanced Usage Examples:**
128
129
```javascript
130
import { createI18nMessage } from "@vuelidate/validators";
131
import { useI18n } from "vue-i18n";
132
133
const { t } = useI18n();
134
135
// Advanced configuration with custom path and parameter factories
136
const withI18nMessage = createI18nMessage({
137
t,
138
139
// Custom message path generation
140
messagePath: (params) => {
141
const validator = params.$validator;
142
const property = params.$property;
143
return `validation.${validator}.${property}`;
144
},
145
146
// Custom parameter processing
147
messageParams: (params) => ({
148
...params,
149
fieldName: params.property.charAt(0).toUpperCase() + params.property.slice(1),
150
currentLength: params.model ? params.model.length : 0
151
})
152
});
153
```
154
155
## Integration Examples
156
157
### Vue I18n Integration
158
159
Complete example showing integration with Vue I18n library.
160
161
```javascript
162
// i18n/messages.js
163
export const messages = {
164
en: {
165
validation: {
166
required: "The {property} field is required",
167
email: "The {property} field must be a valid email address",
168
minLength: "The {property} field must be at least {min} characters long",
169
maxLength: "The {property} field must not exceed {max} characters",
170
between: "The {property} field must be between {min} and {max}",
171
sameAs: "The {property} field must match {otherName}"
172
}
173
},
174
es: {
175
validation: {
176
required: "El campo {property} es requerido",
177
email: "El campo {property} debe ser un email válido",
178
minLength: "El campo {property} debe tener al menos {min} caracteres",
179
maxLength: "El campo {property} no debe exceder {max} caracteres",
180
between: "El campo {property} debe estar entre {min} y {max}",
181
sameAs: "El campo {property} debe coincidir con {otherName}"
182
}
183
},
184
fr: {
185
validation: {
186
required: "Le champ {property} est requis",
187
email: "Le champ {property} doit être une adresse email valide",
188
minLength: "Le champ {property} doit contenir au moins {min} caractères",
189
maxLength: "Le champ {property} ne doit pas dépasser {max} caractères",
190
between: "Le champ {property} doit être entre {min} et {max}",
191
sameAs: "Le champ {property} doit correspondre à {otherName}"
192
}
193
}
194
};
195
196
// validation.js
197
import { createI18nMessage, required, email, minLength, maxLength, between, sameAs } from "@vuelidate/validators";
198
import { useI18n } from "vue-i18n";
199
200
export function useValidationRules() {
201
const { t } = useI18n();
202
203
const withI18nMessage = createI18nMessage({
204
t,
205
messagePath: (params) => `validation.${params.$validator}`,
206
messageParams: (params) => ({
207
property: params.$property,
208
...params.$params
209
})
210
});
211
212
return {
213
required: withI18nMessage(required),
214
email: withI18nMessage(email),
215
minLength: (min) => withI18nMessage(minLength(min)),
216
maxLength: (max) => withI18nMessage(maxLength(max)),
217
between: (min, max) => withI18nMessage(between(min, max)),
218
sameAs: (equalTo, otherName) => withI18nMessage(sameAs(equalTo, otherName))
219
};
220
}
221
222
// component.vue
223
<template>
224
<form>
225
<input v-model="form.username" :class="{ error: $v.username.$error }" />
226
<span v-if="$v.username.$error">{{ $v.username.$errors[0].$message }}</span>
227
228
<input v-model="form.email" :class="{ error: $v.email.$error }" />
229
<span v-if="$v.email.$error">{{ $v.email.$errors[0].$message }}</span>
230
</form>
231
</template>
232
233
<script>
234
import { useVuelidate } from '@vuelidate/core';
235
import { useValidationRules } from './validation.js';
236
237
export default {
238
setup() {
239
const rules = useValidationRules();
240
241
const form = reactive({
242
username: '',
243
email: ''
244
});
245
246
const validationRules = {
247
username: {
248
required: rules.required,
249
minLength: rules.minLength(3)
250
},
251
email: {
252
required: rules.required,
253
email: rules.email
254
}
255
};
256
257
const $v = useVuelidate(validationRules, form);
258
259
return { form, $v };
260
}
261
};
262
</script>
263
```
264
265
### React i18next Integration
266
267
Integration example with React and i18next library.
268
269
```javascript
270
// i18n/resources.js
271
export const resources = {
272
en: {
273
validation: {
274
required: "{{field}} is required",
275
email: "{{field}} must be a valid email address",
276
minLength: "{{field}} must be at least {{min}} characters long",
277
maxLength: "{{field}} must not exceed {{max}} characters"
278
}
279
},
280
de: {
281
validation: {
282
required: "{{field}} ist erforderlich",
283
email: "{{field}} muss eine gültige E-Mail-Adresse sein",
284
minLength: "{{field}} muss mindestens {{min}} Zeichen lang sein",
285
maxLength: "{{field}} darf {{max}} Zeichen nicht überschreiten"
286
}
287
}
288
};
289
290
// hooks/useValidation.js
291
import { createI18nMessage, required, email, minLength } from "@vuelidate/validators";
292
import { useTranslation } from "react-i18next";
293
294
export function useValidation() {
295
const { t } = useTranslation();
296
297
const withI18nMessage = createI18nMessage({
298
t: (key, params) => t(`validation.${key}`, params),
299
messageParams: (params) => ({
300
field: params.$property,
301
...params.$params
302
})
303
});
304
305
return {
306
required: withI18nMessage(required),
307
email: withI18nMessage(email),
308
minLength: (min) => withI18nMessage(minLength(min))
309
};
310
}
311
```
312
313
### Custom Translation Integration
314
315
Example with custom translation system.
316
317
```javascript
318
// Custom translation function
319
function customTranslate(key, params) {
320
const translations = {
321
'validation.required': 'Field {property} is required',
322
'validation.email': 'Field {property} must be valid email',
323
'validation.minLength': 'Field {property} needs {min} characters minimum'
324
};
325
326
let message = translations[key] || key;
327
328
// Simple parameter replacement
329
Object.keys(params).forEach(param => {
330
message = message.replace(`{${param}}`, params[param]);
331
});
332
333
return message;
334
}
335
336
// Create i18n validator factory
337
const withI18nMessage = createI18nMessage({
338
t: customTranslate,
339
messagePath: (params) => `validation.${params.$validator}`,
340
messageParams: (params) => ({
341
property: params.$property.toLowerCase(),
342
...params.$params
343
})
344
});
345
346
// Usage
347
const validationRules = {
348
email: {
349
required: withI18nMessage(required),
350
email: withI18nMessage(email)
351
}
352
};
353
```
354
355
## Best Practices
356
357
### Message Key Organization
358
359
```javascript
360
// Recommended message key structure
361
const messageStructure = {
362
validation: {
363
// Core validators
364
required: "Field is required",
365
366
// Format validators
367
email: "Must be valid email",
368
url: "Must be valid URL",
369
370
// Length validators
371
minLength: "Must be at least {min} characters",
372
maxLength: "Must not exceed {max} characters",
373
374
// Value validators
375
minValue: "Must be at least {min}",
376
maxValue: "Must not exceed {max}",
377
between: "Must be between {min} and {max}",
378
379
// Conditional validators
380
requiredIf: "Required when {condition}",
381
sameAs: "Must match {otherName}"
382
}
383
};
384
```
385
386
### Parameter Naming Consistency
387
388
```javascript
389
// Consistent parameter naming across languages
390
const withI18nMessage = createI18nMessage({
391
t,
392
messageParams: (params) => ({
393
// Normalize parameter names
394
field: params.$property,
395
value: params.$model,
396
min: params.$params.min,
397
max: params.$params.max,
398
otherField: params.$params.otherName
399
})
400
});
401
```
402
403
### Fallback Message Strategy
404
405
```javascript
406
// Fallback strategy for missing translations
407
const withI18nMessage = createI18nMessage({
408
t: (key, params) => {
409
const translated = i18n.t(key, params);
410
411
// Fallback to English if translation missing
412
if (translated === key) {
413
return i18n.t(key, { ...params, lng: 'en' });
414
}
415
416
return translated;
417
}
418
});
419
```