defineMessages

See source code

Declares messages so the extractor can find them, next to the UI that shows them — the English then lives with the code rather than in a catalog edited by hand. Call it by this name: formatjs extract matches the call by name, wherever it was imported from, so a wrapper under another name extracts nothing.

Write the id yourself, as the SDK's own messages do — an app overrides by id, so an id has to survive a reworded English string. Leave it out only where a bundler plugin injects one; with no plugin either the English stands in, so the message still renders as itself. An id missing from a real build is caught by pnpm i18n-extract --check.

The type parameter is const so each written id keeps its literal type, which is what lets a declared id go where a TLUiTranslationKey is expected — a menu item's label, say — instead of widening to string and needing a cast.

For a message rendered as an element, write it inline on the <F> instead; the extractor reads those props directly. This is for the ones that can't be: a label the UI takes as data, and anything translated as a string through useTranslation.

function defineMessages<
  const Messages extends Record<string, TLI18nMessageInput>,
>(
  msgs: Messages,
): {
  [K in keyof Messages]: Messages[K] & TLI18nMessage;
};

Example

const messages = defineMessages({
  copy: { id: "action.copy", defaultMessage: "Copy" },
});

Parameters

NameDescription

msgs

Messages;

Returns

{
  [K in keyof Messages]: Messages[K] & TLI18nMessage;
};
Prev
defaultI18n
Next
degreesToRadians