Median

Conversations

What a visitor sees in the support panel, and how a thread behaves from the first message to the rating.

Updated Oct 1, 202610 minute read

Thread lifecycle

MomentWhat happens
The panel opens with no historyThe empty state shows. Nothing is stored about the visitor yet
First messageCreates the customer and a conversation. The message becomes the conversation's title in the inbox. With telemetry on, the page it was sent from is kept as Started on
Later messagesJoin the open conversation
The conversation is resolved or closedThe rating card appears above the composer. The composer stays
The next messageStarts a new conversation. The old one stays above a New conversation divider
A message on a conversation your team archived or snoozedUnarchives it and clears the snooze
  • A visitor has one open widget conversation at a time.
  • A visitor is one browser, kept by a token in localStorage. With a signed identity, a visitor is one person on every device.
  • The panel shows up to 10 recent conversations and the newest 200 messages across them. A date line separates days.
  • A teammate resolves a conversation in the inbox. The agent resolves finished ones itself while Resolve conversations automatically is on under Agent → Behavior, and says goodbye first.
  • The same switch lets the agent close spam. A closed conversation looks resolved to the visitor.
  • With Review the inbox nightly on under Agent → Behavior, a nightly pass resolves answered conversations that are still open. It is on by default.
  • An email from the same customer continues their email thread, never the widget thread.

Empty state

A panel with no history shows the agent's picture and name, How can we help you with Acme? with your workspace name, and three rows.

RowSends
Ask a questionI have a question
Report a bugI want to report a bug
Make a suggestionI have a suggestion
  • A row sends its message at once, as the visitor.
  • The rows are disabled while the email question shows.
  • No prop hides them.

Email question

The composer asks for an email before the visitor writes. It shows only when all of these hold:

  • requireEmail is true. That is the default.
  • Ask for an email is on under Agent → Behavior. That is the default.
  • user.email is empty.
  • This browser has not given an address yet.

What the visitor sees:

  • A tab reading Enter your email rises over the composer, and the message box becomes an email field.
  • The arrow turns on once the text looks like an address. Enter also submits. Nothing checks that the address exists.
  • Saved shows for a moment, then the message box returns.
  • Files cannot be attached while the question shows.

The address is stored in this browser under median:email:<id>. It rides every later message and lands on the customer's record, unless user.email is set. A send from MedianContactForm stores it the same way, so the widget stops asking. reset() removes it.

Replies

The visitor seesMeaning
The agent's name with an AI badgeThe AI wrote the reply
A teammate's name and faceA person on your team wrote it. A teammate when they have no name
Three dots in a bubbleA reply is being written
Waiting for the support team above the composerThe agent handed the thread to a person, or a teammate took it over. Clears when a teammate replies
An image with no text, sent as the visitorThe agent asked to see the page. See Context and diagnostics
A red line above the composerA send failed. The messages are under Attachments
  • The header shows your workspace name, Support online, and the faces of the agent and up to two teammates who replied. While the panel connects, it shows Support and Connecting.
  • The AI answers first, unless the thread is waiting on a person.
  • One AI turn arrives as up to four messages, with dots between them. Each pause is 0.7 to 2.5 seconds, longer before a longer message.
  • If the visitor writes while the AI is answering, the answer starts over with the new message included.
  • A teammate's dots disappear 12 seconds after their last keystroke.
  • Your team sees when the visitor is typing, never the text. The widget sends the signal at most every 2.5 seconds and stops it after 8 seconds without a keystroke. Before the first message and on a resolved conversation, the signal is ignored and your team sees nothing.

Unread replies

A reply is unread until the visitor has the panel open in a visible tab.

SignalShowsTurn it off
Count on the launcherUnread replies, 9+ above ninelauncher="hidden" removes it with the launcher
Card over the launcherThe sender's name and face, and the first two lines of the newest replymessagePreview={false}, or Preview replies under Agent → Behavior
Tab title(2) Your page titletitleCount={false}
SoundA short chime at 45% volumeNo switch
  • Pressing the card opens the panel.
  • The cross on the card hides it in this browser. Screen readers announce it as Dismiss. The count stays until the panel opens. A newer reply brings a new card.
  • The card sits below the launcher when the launcher was dragged near the top of the window.
  • With launcher="hidden", there is no count and no card. Read unreadCount from useMedianSupport for a badge of your own.
  • Median stores read state per conversation. A reply read on one device is read on every device that shares the thread.
  • Your own title comes back once the replies are read. If your router changes the title while the count shows, the count moves to the new title.
  • The sound plays for each new written reply, with the panel open or closed. Replies that land together play once.
  • History loaded with the page never plays a sound, and neither does the thread that arrives on sign in.
  • Browsers keep the sound silent until the visitor has interacted with the page.

Email copies of missed replies

When the visitor is not watching the panel, Median emails the replies they missed. All three must be true:

  • The visitor has an email address, from user.email, the email question, or the contact form.
  • Email support is set up and turned on. See Email.
  • The visitor has opened the panel at least once, or wrote in through the contact form. A client that never reports presence, such as one built on the REST API, is never emailed.
StepTiming
The open panel reports presenceWhen the panel opens, every 45 seconds after, and when the tab becomes visible or regains focus. Only while the tab is visible
Median checks after a reply lands2 minutes later
The visitor counts as awayNo presence in the last 90 seconds
  • The missed replies go out in one email, from your support address, with the subject Re: <conversation title>. Without a title, the subject is Re: your message.
  • The sender name is Ada at Acme when one writer wrote every reply in it, and Acme otherwise.
  • Replies already read on any device, replies already emailed, and replies older than the visitor's last message are left out.

Ratings

When a conversation is resolved, a card above the composer asks How did we do? with five stars.

  • A star saves the rating the moment it is pressed. Pressing another star changes it.
  • After a star, the card asks Anything we could improve? with an optional box, up to 1,000 characters.
  • The button reads Done while the box is empty and Send once it has text. Sent words are added to the same rating. An empty box never removes earlier words.
  • Thanks for the feedback. shows, then the card folds away.
  • Skip closes the card without a rating. A skip is remembered in this browser only. A rating stops the card on every device.
  • If saving fails, the card shows Could not submit your rating. Try again.
  • The next conversation gets its own card when it ends.

Ratings roll up into Satisfaction in Analytics.

Pages and highlights

One of your tools can offer the visitor a page and point at something on it. Writing those tools is on Pages and highlights.

The visitor seesWhen
Take me there under a replyThe reply carried a destination and you passed onNavigate
Take me there above the composerA teammate ran the tool, or approved it after the reply. Shown for 5 minutes after the run
A ring around an element, scrolled into viewA highlight arrived on its own, or the visitor pressed a button that carried one
  • The page never changes on its own. Pressing the button calls onNavigate with the path.
  • The path must start with / and stay on the page's origin. Anything else logs Median: refused to navigate to {path}, which is not a path on this site.
  • A button under a reply stays with the reply. The one above the composer goes once pressed.
  • On phones and in the support modal, pressing the button closes the panel. The corner panel stays open.
  • A highlight on its own is drawn once, as the reply arrives. Highlights older than 5 minutes, and highlights in history, are not drawn.
  • The ring waits up to 4 seconds for the element, stays for about 2.6 seconds, then fades. It sits over your page, takes no clicks, and changes none of your styles.
  • A selector the browser cannot parse logs Median: a tool asked to highlight {selector}, which is not a valid CSS selector.
  • Without onNavigate, no button shows. In development the console says so.

Attachments

LimitValue
Message length4,000 characters
Files per message6
File size25 MB each
Refused typestext/html, application/xhtml+xml, image/svg+xml, text/xsl, application/xslt+xml
  • Attach with Add an attachment (the plus button), by dropping files on the composer, or by pasting. The box reads Drop to attach while a file is over it.
  • A file over 25 MB shows Larger than the 25 MB limit on its chip. A refused type shows This kind of file cannot be sent. Either one blocks sending until it is removed.
  • The composer does not count files. A seventh file fails on send.
  • A failed send keeps the draft and its files. Text typed while a message was sending stays in the box.
  • What the agent reads from files is on Built-in abilities.

A failed send shows one of these above the composer:

CodeMessage
empty_messageEnter a message or attach a file.
message_too_longMessages have to be 4000 characters or fewer.
too_many_attachmentsMessages can carry 6 files at most.
attachment_too_big"photo.png" is larger than the 25 MB limit.
attachment_wrong_type"page.html" is a kind of file we cannot accept. Send it as a screenshot or a plain text file.
attachment_missing"photo.png" did not finish uploading. Try sending it again.
rate_limitedToo many requests. Wait a moment and try again.

Any other error Median raises shows its own message. A tab running an old widget build shows This page is out of date. Refresh to get the latest version. Anything else, including a failed upload, shows Something went wrong on our end. Please try again.

Keyboard

KeyWhereDoes
EnterMessage boxSends
Shift+EnterMessage boxAdds a line
EnterEmail fieldSaves the address
EscapeAnywhere on the page while the panel is openCloses the panel
  • Enter while an input method is composing picks the candidate and does not send.
  • Opening moves focus into the panel, not onto the composer, so a phone does not raise its keyboard. Closing returns focus to the launcher, or to the element that opened the panel.
  • The thread is a polite live region. Screen readers announce new replies without moving focus.

Placement and size

PartSize
Launcher3rem circle, 1rem from the edge, bottom right until moved
Panel28rem wide, 40rem tall
Expanded panel34rem wide, 52rem tall
Viewport 40rem (640px) wide or lessFull screen
  • The panel never grows past the viewport, keeping 1rem clear on each side.
  • Expand the panel in the header switches to the expanded size, and Shrink the panel switches back. The choice lasts until the page reloads.
  • Visitors can drag the launcher, or the open panel by its header. It snaps to the nearest side and keeps its height as a fraction of the window, so a resize keeps it on screen.
  • On a phone, the panel follows the on-screen keyboard, the page behind it does not scroll, and there is no expand control. Only the launcher drags.
  • MedianSupportModal opens in the middle of the screen instead. Colors, fonts and motion are on Theming.

Browser storage

<id> is the widget's median_pk_ id.

localStorage keyHoldsCleared by reset()
median:session:<id>A random token that names this browser's visitorYes
median:email:<id>The address from the email question or the contact formYes
median:rating-skips:<id>The last 20 conversations whose rating card was closed, by Skip or after finishingNo
median:teaser:<id>When the reply on the last dismissed card was sentNo
median:launcher-spotThe launcher's side and height, shared by every widget on the siteNo
  • The widget sets no cookies.
  • If localStorage is blocked, each value lasts the page load. A reload then starts a new visitor.
  • reset() removes the session and email keys for every widget id in the browser. See Identity.

Rate limits

ScopeCountsRateBurst
OrganizationMessages, contact form sends, ratings, feedback notes and crash reports120 a minute30
OrganizationNew conversations30 a minute15
OrganizationFile uploads, one per file300 a minute60
OrganizationTyping, presence and identity checks1,200 a minute300
One browserSends, file uploads and identity checks30 a minute15

Over a limit, the send fails with Too many requests. Wait a moment and try again. above the composer. The draft stays. REST API limits are on Errors and limits.

Still need help?

    Esc