Merge Field Check

Renders a mail-merge template for each real recipient, so nothing goes out as "Hi ," or "{{frist_name}}".

StopsEmail went out as Hi {{first_name}}

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/merge-field-check.json

The files land in your project. They're yours to edit.

Usage

merge-field-check-usage.tsx
import { MergeFieldCheck, type MergeRecipient } from "@/components/ui/merge-field-check"

return <MergeFieldCheck value={template} onValueChange={setTemplate} recipients={recipients} />

What it catches

  • Unknown fields, with typo suggestions (frist_name → first_name)
  • Broken braces such as {first_name}} or {{first_name,
  • Recipients with an empty or whitespace-only value
  • Missing fallbacks: adds {{field | default: "there"}}

Props

MergeFieldCheck props
PropTypeDefault
value

The template (controlled), using `{{field}}` and `{{field | default: "there"}}`.

string—
defaultValue

Starting template when uncontrolled.

string""
onValueChange

Called with the template after every edit or one-tap fix.

(value: string) => void—
recipients* (required)

The real audience, one row per recipient.

MergeRecipient[]—
fields

Fields that exist. Defaults to every key found on the recipients.

string[]—
fallbacks

Suggested fallback per field. Name-like fields default to "there".

Record<string, string>{}
getRecipientLabel

How a recipient is named in the stepper. Defaults to email, phone or name.

(recipient: MergeRecipient, index: number) => string(r, i) => r.email ?? r.phone ?? r.name ?? `Recipient ${i …
label

Visible label.

string"Message"
previewLabel

Label above the per-recipient preview.

string"Preview as"
nextProblemLabel

Button text to step to the next recipient with a gap.

string"Next problem"
cleanText

Shown when nothing needs fixing. `{count}` is the audience size.

string"Every field fills in for all {count}."

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Visible label; textarea has aria-invalid for template errors and is described by the issues list
  • Issues list is a polite live region
  • Fixes are buttons; focus returns to the textarea

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Understands {{field}} and {{field | default: "…"}} only, not full Liquid or Handlebars
  • Checks the recipients you pass, not your whole list

What it stops

Email went out as Hi {{first_name}}

Also known as

mail merge · merge tags · template · personalization · email campaign · sms template · handlebars · first name

Field type

Dependencies

Pairs well with