Skip to content
Consultation

MessageCircle Is Not WhatsApp, the Client Told Me So

Adityo Guni Waluyo

A WhatsApp CTA with a generic lucide chat icon made visitors hesitate. The fix: an inline brand SVG, a real label, and better button contrast.

The client sent a screenshot of the contact page on Tuesday morning: "This button doesn't look like WhatsApp, people hesitate to click it." The CTA in question ran on MessageCircle from lucide-react, a generic one-bubble chat icon, with a label showing only the last 4 digits of the number via wa.slice(-4). So visitors read something like 1234 next to a balloon glyph. The section background was the brand primary color, the button a thin outline. On my bright screen it looked fine. On the client's phone, it vanished.

My first guess was contrast. Wrong. Once I inspected the elements, the real problem was the shape of the icon. Nobody reads "Chat 1234" and thinks "oh, WhatsApp". They look for a shape they already know: the green-and-white logo. MessageCircle is neutral, not a brand, and no visitor's brain connects a generic chat balloon to a specific messaging app.

And lucide will never ship one. They officially refuse brand logos, citing legal and trademark restrictions, design consistency, and maintenance burden; their official recommendation is Simple Icons (Lucide's brand logo statement). As of June 2026, the v1.0 release went further and removed all remaining brand icons under legal pressure (InfoQ). Waiting for lucide to add a WhatsApp glyph is waiting for rain in the dry season. Nothing was broken in my code; this is a library limitation. But making the button work for the client's business was still my job.

Three changes in commit 2f5d546

First, a dedicated WhatsAppIcon component. Inline SVG with the official WhatsApp path, viewBox="0 0 24 24", fill="currentColor" so it inherits the button's text color, and aria-hidden because it's decorative, the text label carries the accessible name. No new dependency for one icon: a 19-line file in components/shared/, and the bundle doesn't move.

export function WhatsAppIcon({ className }: WhatsAppIconProps) {
  return (
    <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden className={cn("size-5", className)}>
      <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967..." />
    </svg>
  );
}

Second, the 4-digit label died. In contact-offices-section.tsx and quick-contact-section.tsx, the wa.slice(-4) is gone, replaced by icon plus a full label. Visitors no longer guess whose number ends in 1234.

Third, the outline button over the primary background. Border at primary-foreground/40, transparent background, hover switching to a full border plus a semi-solid fill. WCAG 2.1 requires a 4.5 to 1 contrast ratio for text and 3 to 1 for large text (W3C). A hairline white outline on a light color is exactly the kind of combination that fails a contrast check, especially on a sun-glared screen. With the more solid hover state, every button state holds a reasonable ratio.

Two number-sanitization approaches in one repo

The CTA link uses the wa.me format, and rereading the patch surfaced a detail I'd missed. The correct click-to-chat format: wa.me followed by the full international number, no plus sign, no leading zeros, no dashes. Get it wrong and WhatsApp shows an invalid-number error (WhatsApp FAQ). The numbers in this repo come from JSON data and were already clean, so the template is a plain concatenation of the base URL and the number, no processing.

But in the same component tree, the phone number for the tel: link gets scrubbed with replace(/[^0-9+]/g, "") before use. Two philosophies in one repo: one trusts the data, one sanitizes at runtime. Neither is technically wrong, but someday a number will arrive through a different path and one of these assumptions will break. Unifying them is a job for another day.

My firm take: brand icons on CTAs are not vanity. Users don't read labels, they recognize shapes. A generic chat icon on a page whose whole purpose is getting people to make contact is pure friction. If someone argues "neutral icons look cleaner", I disagree for conversion pages. I also chose inlining the SVG myself over adding the simple-icons package for a single path. If ten more brands show up someday, I'll reconsider.

The button now: WhatsApp glyph on the left, full label on the right, an obvious hover. The client's reply: "now it actually feels like WhatsApp."

Related articles