Skip to content

Messaging ​

Manage and format messages consistently across rules, locales, and groups. Ensure clarity through structured placeholders and organized grouping for related rules.

🧠 Rule Level ​

Resolving a message when a field fails goes through different levels – group, locale and rule. Without a group handler or a locale source, the resolver falls back to the rule. The most common way is using the message property – the default message.

js
defineRule('minlength', {
  validate: (value, [limit]) => {
    return value.length >= limit
  },
  message: 'The {field} must be at least {limit} characters long.'
})

Another common way is through an explicit message. Return a single message or chain multiple conditions with nested messages for a more dynamic messaging.

js
defineRule('maxlength', {
  validate: (value, [limit]) => {
    if (value.length > limit) {
      return 'The {field} must be no more than {limit} characters long.'
    }
  }
})

🌐 Locale Level ​

With a locale source, a false result turns into a resultKey using the defined rule name. This key is used to lookup a locale source and retrieve its localized message when available. A resultKey can be returned directly, which will have the same effect.

js
defineRule('minlength', {
  validate: (value, [limit]) => {
    return value.length >= limit
  }
})

const fr = {
  names: {},
  messages: {
    minlength: 'Le {field} doit contenir au moins {limit} caractères.'
  }
}

localize({ fr })

πŸ—ƒοΈ Group Level ​

The group handler will act as an override to any defined messages. It can also return either an explicit message or a resultKey which resolves to a localized message.

js
defineRule('minlength', {
  validate: (value, [limit]) => {
    return value.length >= limit
  }
})

defineRule('maxlength', {
  validate: (value, [limit]) => {
    return value.length <= limit
  }
})

const ext = extendMessage(formEl)

ext.groupMessage({
  rules: ['minlength', 'maxlength'],
  message: 'Length of {field} must be between {minlength} and {maxlength}.'
})

πŸ’¬ Resolving ​

The resolver follows a structured flow to determine the final message for a rule. This process ensures that localization, group handlers, and fallbacks are applied consistently.

1. resultKey Resolution ​

When evaluating a rule, the resultKey is determined to resolve the final message:

Rule ResultAction
falseresultKey becomes the rule name, then resolveMessage() is called
stringThe string is used as resultKey and passed to resolveMessage()

2. resolveMessage Logic ​

The resolver behaves differently depending on whether a group handler is present:

HandlerSummary
YesRetrieve context via handler, localize the message, and return the context.
NoReturn either the localized message, default message, or a fallback if undefined.

βœ… With Handler ​

  • Retrieve the context through the group handler.
  • Localize the message within the context using i18n.getMessage().
  • Return the context object immediately w/o further processing.

❌ Without Handler ​

  • Localize the resultKey using i18n.getMessage().
Localize ResultRule MessageAction
string != 'ruleName'N/AReturn the localized message
string == 'ruleName'YesFallback to the rule’s rule message
string == 'ruleName'NoFallback to "The {field} field is invalid."

πŸ’‘ Notes ​

  • The default message is the message attribute defined under defineRule().
  • Group handlers allow dynamic or contextual messages for a set of rules.
  • Fallbacks ensure that a message is always available, even if localization is missing.
  • This system works seamlessly with the formatting system described here.

Released under the MIT License.