Rich messages in Freshchat exist on a spectrum from “small button under a reply” to “carousel of seven product cards with images”. The far end of that spectrum is where bots quietly fail — payloads that render fine on desktop, collapse on iOS, and exceed WhatsApp’s stricter limits when you bridge the same flow there. This is the design-system view, not a feature tour.
Pick the card type before the content
Freshchat ships four primary rich types: quick replies, buttons, carousels, and decision cards. They are not interchangeable. Pick by intent:
- Quick replies — disambiguation. Three to five short labels. Disappear after selection. Use when you are routing.
- Buttons — committed actions. Persist in transcript. Use when the user is choosing an action with consequences (escalate, schedule, open URL).
- Carousel — comparison. Two to five items, never more. Use when the user is picking one of many similar things.
- Decision card — a single hero with structured fields and one or two CTAs. Use when there is one recommended path and a fallback.
The most common mistake is using carousel as a menu. Carousels are for shopping, not for navigation. A six-card carousel where each card is a topic is a menu pretending to be retail. Use a list or quick replies.
Payload limits that bite
Freshchat documents the field-level limits, but the platform-level ones matter more. Across the supported channels (web, in-app, WhatsApp, Apple Messages for Business, Messenger) you can assume:
- Title: 80 chars safe, truncated past that on iOS web SDK.
- Subtitle / description: 160 chars safe. WhatsApp interactive list rows cap closer to 72.
- Buttons per card: 3 maximum, even though the editor lets you add more.
- Cards per carousel: 5 reliable; 10 may render on web but degrade on mobile.
- Image: 1.91:1 aspect on web, square works better on WhatsApp.
Design for the strictest channel you actually ship to. Building two parallel payloads for web vs WhatsApp is a maintenance tax most teams cannot afford long-term.
The decision card pattern
This is the highest-converting pattern we have measured across deployed bots. One hero card, a four-line summary, one primary CTA, one secondary CTA, and a quick-reply row underneath for “not what I needed”.
{
"response_type": "card",
"card": {
"title": "Reset your password",
"subtitle": "Takes about 30 seconds. We will email a link to the address on file.",
"image_url": "https://cdn.acme.com/bot/reset-hero.png",
"buttons": [
{ "type": "url", "label": "Start reset", "url": "https://acme.com/reset" },
{ "type": "postback", "label": "Talk to an agent", "payload": "ESCALATE_AUTH" }
]
},
"quick_replies": [
{ "label": "That is not my issue", "payload": "RESET_WRONG_INTENT" }
]
}
Two important details. First, postback payloads should be opaque, uppercase, snake-case identifiers — not user-visible strings. Second, the “that is not my issue” quick reply is non-negotiable. Bots without an escape hatch generate furious reviews. Always offer it.
Carousel layout discipline
Carousels work when the items are genuinely comparable on the same handful of fields. A three-plan pricing carousel is fine. A carousel where card one is a knowledge article, card two is a video, and card three is a contact form is a UX failure.
Rules I enforce in design review:
- Every card has the same field set in the same order.
- Every card has the same CTA verb. If card one says “Choose” and card two says “Buy”, you are confusing the user.
- Card order is meaningful — most-popular or recommended first, never alphabetical.
- Image style is consistent across cards. A mix of photo and illustration on adjacent cards looks broken even when it is not.
Mobile-first widths
The Freshchat web widget defaults to a 400 px conversation column. The chat surface inside it is closer to 320 px usable, less on the iOS in-app SDK. Long button labels wrap into ugly two-line buttons. Test every CTA at 320 px before shipping.
A simple way: open the widget on desktop, narrow the browser window to phone width, and walk through the bot flow. If any button wraps, shorten the label. “Schedule a call with our sales team” becomes “Schedule a call”. “Get a personalised quote in 2 minutes” becomes “Get a quote”.
Postback hygiene
Postback payloads are how rich messages connect back into the bot flow. Treat them like an internal API:
- Versioned:
RESET_AUTH_V2notRESET_AUTHwhen you change handler behaviour. - Namespaced:
BILLING.OPEN_INVOICErather than free-floating tokens. - Documented: maintain a single registry article so bot builders and analytics share vocabulary.
The analytics consequence is large. Postback strings show up in funnel reports and intent analysis. Renaming them mid-quarter destroys trend continuity. Pick names you can live with for a year.
Quick replies are not survey questions
There is a temptation to use quick replies for satisfaction surveys mid-conversation. Resist. Quick replies are routing UI, not measurement UI. A “Was this helpful? Yes / No” quick reply mid-flow biases the survey toward whoever was already going to bounce.
For CSAT, use the dedicated survey trigger at the end of the conversation. See freshchat-bot-builder for how to anchor the survey to bot completion rather than session end.
Image guidelines
The widget caches images aggressively but cold loads on mobile data are visible. Rules:
- Serve from a CDN with
Cache-Control: public, max-age=31536000. - Keep hero images under 80 KB. WebP if your stack supports it, otherwise compressed PNG.
- Use a 1.91:1 aspect ratio for cards rendered on web. Crop centrally — Freshchat does not always honour
object-position. - Never put text in images. The bot widget does not respect screen reader zoom for image text.
Accessibility floor
Every interactive element needs a clear label. The widget renders buttons as native <button> elements with the label as accessible text — so a button labelled “Click here” reads “Click here” to a screen reader, which is useless. Use full verb phrases: “Start password reset”, “Schedule appointment”.
Carousel navigation is keyboard-accessible by default but only if the cards have meaningful titles. Title should describe the choice, not be a marketing tagline.
Bottom line
Rich messages are a design system, not a feature menu. Pick the right card for the user’s job, design for the narrowest channel and screen, keep postback names stable, and always offer an escape from the bot. The carousel of seven looks impressive in admin and converts terribly in production — five cards, three buttons, one decision per card.