3.2 KiB
stringify-children
Purpose
Helpers that translate a <Trans> children block into a canonical
ICU message body string so the message parser renders a missing-key
fallback identically to a catalog entry. The module exists as a sibling
of <Trans> (rather than inline) so the trans component file stays
within the per-file size budget and so the structurally-invalid-child
branch can be unit-tested directly without going through React's JSX
surface (which validates and rejects invalid children before they
reach our Children.forEach callback).
Features
childrenToMessageString— entry point that walksChildren.forEachand concatenates each child's stringified formstringifyChild— single-child stringifier, exported for direct unit testing of the defensiveTRANS_INVALID_CHILDthrow- Nested children are recursed; tag-wrapped children render as
<tagName>...</tagName>with the same component-map semantics - Boolean,
null, andundefinedchildren render as the empty string (matches React's own rendering rules) - Defensive throw of
ReactI18nError(REACT_I18N.TRANS_INVALID_CHILD)for any structurally-invalid value (functions, custom objects)
Usage: Basic Example
import { childrenToMessageString } from "@suaveplan/react-i18n/components/trans/stringify-children";
const body = childrenToMessageString(
<>Hello <strong>{"{name}"}</strong>!</>,
"absent.key"
);
// body === "Hello <strong>{name}</strong>!"
Usage: Advanced Example
The helpers operate purely on React children, so consumers can use
them outside <Trans> for snapshot / logging surfaces where a
React-children tree needs a stable string serialisation:
import { stringifyChild } from "@suaveplan/react-i18n/components/trans/stringify-children";
function snapshotChild(node: React.ReactNode): string {
try {
return stringifyChild(node, "snapshot");
} catch (err) {
return `[invalid: ${(err as Error).message}]`;
}
}
API Reference
childrenToMessageString(children: ReactNode, key: string): string
Walks React.Children.forEach over children and concatenates each
result of stringifyChild. Returns the literal key string when
children is null or undefined.
stringifyChild(child: ReactNode, key: string): string
Stringifies one React child. Recurses into element children via
childrenToMessageString for the tag body. Throws
ReactI18nError(REACT_I18N.TRANS_INVALID_CHILD) with context: { key }
for structurally-invalid input.
Implementation Notes
- The module is intentionally side-effect-free; both helpers are pure string returners with the single exception of the defensive throw.
- Element children with no
props.childrenproduce<tagName></tagName>rather than<tagName>key</tagName>— the nested-children helper reads the children prop with a fall-through to the empty string so the recursion does not mistakenly inject the outer key into a childless tag body. - The defensive throw exists for the edge case where TypeScript's
ReactNodetyping is bypassed by a caller who hand-constructs a child viaReact.createElement. In typical JSX usage React's own pre-render validation rejects invalid values before our callback runs.