Skip to content
On this page

I18n

To translate your error messages, you can use the vue-i18n package and zod to set global, translated messaged.

ts
import { z } from 'zod'
import i18n from '@/plugins/i18n'

const customErrorMap: z.ZodErrorMap = (issue, ctx) => {
  const t = i18n.global.t
  if (issue.code === z.ZodIssueCode.invalid_type)
    return { message: t('errors.invalid_type') }

  if (issue.code === z.ZodIssueCode.invalid_union)
    return { message: t('errors.invalid_union') }
  if (issue.code === z.ZodIssueCode.invalid_string) {
    if (issue.validation === 'email')
      return { message: t('errors.invalid_email') }
    if (issue.validation === 'url')
      return { message: t('errors.invalid_url') }
    if (issue.validation === 'uuid')
      return { message: t('errors.invalid_uuid') }
    if (issue.validation === 'regex')
      return { message: t('errors.invalid_regex') }
    if (issue.validation === 'datetime')
      return { message: t('errors.invalid_datetime') }

    return { message: t('errors.invalid_string') }
  }

  if (issue.code === z.ZodIssueCode.invalid_date)
    return { message: t('errors.invalid_date') }
  if (issue.code === z.ZodIssueCode.too_big) {
    if (issue.type === 'string')
      return { message: t('errors.too_big_string', { count: issue.maximum }) }
    if (issue.type === 'number')
      return { message: t('errors.too_big_number', { count: issue.maximum }) }
    if (issue.type === 'array')
      return { message: t('errors.too_big_array', { count: issue.maximum }) }
    if (issue.type === 'date')
      return { message: t('errors.too_big_date', { count: issue.maximum }) }
    return { message: t('errors.too_big', { count: issue.maximum }) }
  }
  if (issue.code === z.ZodIssueCode.too_small) {
    if (issue.type === 'string')
      return { message: t('errors.too_small_string', { count: issue.minimum }) }
    if (issue.type === 'number')
      return { message: t('errors.too_small_number', { count: issue.minimum }) }
    if (issue.type === 'array')
      return { message: t('errors.too_small_array', { count: issue.minimum }) }
    if (issue.type === 'date')
      return { message: t('errors.too_small_date', { v: issue.minimum }) }
    return { message: t('errors.too_small', { count: issue.minimum }) }
  }

  return { message: ctx.defaultError }
}

z.setErrorMap(customErrorMap)

const setupZod = (): void => {
  z.setErrorMap(customErrorMap)
}

export default setupZod
json
{
  "errors": {
    "invalid_type": "This field is required.",
    "invalid_email": "Invalid email.",
    "invalid_url": "Invalid URL.",
    "invalid_uuid": "Invalid UUID.",
    "invalid_regex": "Invalid REGEX.",
    "invalid_datetime": "Invalid datetime.",
    "invalid_string": "Invalid text.",
    "invalid_date": "Invalid date.",
    "too_big_string": "Max. {count} characters long.",
    "too_big_number": "Max. {count}.",
    "too_big_array": "Max. {count} elements.",
    "too_big_date": "Max. {count} date.",
    "too_big": "Max. {count} big.",
    "too_small_string": "This field is required. | Min. {count} characters long.",
    "too_small_number": "Min. {count} big.",
    "too_small_array": "Min. {count} elements.",
    "too_small_date": "Min. {count} date.",
    "too_small": "Min. {count} long."
  }
}
ts
import './configs/zod.config'