defineMessages — Typed UI Message Factory
Overview
defineMessages is a powerful utility that helps you manage consistent, typesafe user-facing messages across your app. It merges your custom messages with a base set of predefined messages (mostly for auth, errors, success, and common app states), and provides a convenient, strongly typed method to retrieve messages based on a "type.key" code pattern.
This ensures:
- Centralized message management: Keep all your UI strings in one place, easy to update and extend.
- Type safety: Catch invalid message keys or types at compile time, avoiding runtime bugs.
- Clear intent: Messages are categorized by type (
success,error,warning,message,null) for consistent UI handling.
How It Works
You define or extend your messages by calling defineMessages() with an optional custom map of string keys to messages. This merges your custom keys with the base message map. The returned object exposes a $message function that accepts a code string formatted as "type.key".
typemust be one of the predefined message types:"success" | "error" | "message" | "warning" | "null"keymust be a valid key from the combined message map.
Example codes: "success.ok", "error.auth/user-not-found", "warning.forbidden", "message.profile-updated".
Usage Example
import { defineMessages } from "@/utils/defineMessages"
const { $message } = defineMessages({
testing: "This is a testing message!",
})
const msg1 = $message("success.ok")
// { type: "success", message: "Success! Your request was processed successfully." }
const msg2 = $message("warning.forbidden")
// { type: "warning", message: "You don’t have permission to access this resource." }
const msg3 = $message("error.unknown")
// { type: "error", message: "An unknown error has occurred." }
const msg4 = $message("success.testing")
// { type: "success", message: "This is a testing message!" }
// Invalid usages (will cause TypeScript errors)
// $message("foo.ok") // invalid message type
// $message("success.nosuchkey") // invalid key in message mapAPI
defineMessages(input?: Record<string, string>)
Parameters:
input(optional): Custom messages to extend or override the base message map.
Returns: An object with:
$message<T extends string>(code: T): { type: MessageType; message: string }A function to get the typed message object for a given message code string.
Benefits
- Type-safe messages: You get compile-time checking that message keys and types are valid.
- Easy to extend: Add custom messages without losing type safety.
- Consistent UI behavior: The
typefield can be used to control styling or iconography in your components. - Fallback handling: Unknown keys return a generic error message, preventing undefined text.
Integration Tips
- Use the
$messagefunction in UI components to fetch localized or standard messages. - Extend the base message map in each project or feature as needed.
- Combine with your agency’s i18n strategy for multi-language support (add a localization layer on top).
- Consider integrating with your error handling logic to map backend error codes to user-friendly messages.
Let me know if you want me to generate unit tests for this or add examples for integration with Vue/Nuxt components!