Template Bubble
wa-ui/template-bubbleFreeComponent
WhatsApp Business template message bubble supporting text/image/video/document/location headers and url/phone/quick_reply/copy_code/flow/call_permission buttons.
Live preview
live · rendered by the registry
Rendered by wa-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.meta-cloud-api.site/r/template-bubble.jsonSource
1"use client";23import * as React from "react";4import { Button } from "@base-ui/react/button";5import { cn } from "@/lib/utils";6import "@/components/ui/whatsapp/styles/whatsapp.css";78// ─── Types ────────────────────────────────────────────────────────────────────910type HeaderType = "text" | "image" | "video" | "document" | "location";1112interface LocationHeader {13 name: string;14 address: string;15 imageUrl?: string;16}1718interface TemplateHeader {19 type: HeaderType;20 text?: string;21 imageUrl?: string;22 videoUrl?: string;23 documentName?: string;24 location?: LocationHeader;25}2627export type TemplateButton =28 // CTA — opens URL in browser29 | { type: "url"; label: string; url?: string }30 // CTA — initiates phone call31 | { type: "phone_number"; label: string; phone_number?: string }32 // User reply with pre-set text33 | { type: "quick_reply"; label: string }34 // Copies a coupon/promo code to clipboard35 | { type: "copy_code"; label?: string; code?: string }36 // Opens a WhatsApp Flow37 | { type: "flow"; label: string }38 // Opens a WhatsApp Catalog39 | { type: "catalog"; label?: string }40 // One-tap autofill OTP (authentication templates)41 | { type: "otp"; label?: string }42 // Calling permission request (custom display type)43 | { type: "call_permission"; bizName: string };4445export interface TemplateBubbleProps46 extends React.HTMLAttributes<HTMLDivElement> {47 variant?: "incoming" | "outgoing";48 header?: TemplateHeader;49 body: string;50 footer?: string;51 buttons?: TemplateButton[];52 timestamp?: string;53 /** Override the default `<a>` element for URL/phone buttons (e.g. Next.js Link) */54 renderAction?: (props: { href: string; children: React.ReactNode; className: string; target?: string; rel?: string }) => React.ReactElement;55}5657// ─── Variable highlighting ─────────────────────────────────────────────────5859function BodyText({ text }: { text: string }) {60 const parts = text.split(/(\{\{[^}]+\}\}|\{[^}]+\})/g);61 return (62 <>63 {parts.map((part, i) =>64 /^\{/.test(part) ? (65 <span key={i} className="text-wa-emerald-600">66 {part}67 </span>68 ) : (69 <React.Fragment key={i}>{part}</React.Fragment>70 )71// … truncated
Files it writes
More from wa-ui
All 29 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Action Buttonaction-button | wa-ui | Components | Free | 1 dep · 2 files | |
| Call Permissioncall-permission | wa-ui | Components | Free | 1 dep · 2 files | |
| Carousel Templatecarousel-template | wa-ui | Components | Free | 1 dep · 3 files | |
| Chat Bubblechat-bubble | wa-ui | Components | Free | no deps · 2 files | |
| Chat Headerchat-header | wa-ui | Components | Free | no deps · 2 files | |
| Chat List Itemchat-list-item | wa-ui | Components | Free | no deps · 2 files | |
| Chat Menuchat-menu | wa-ui | Components | Free | 1 dep · 2 files | |
| Contact Bubblecontact-bubble | wa-ui | Components | Free | 1 dep · 3 files |
