Components
Pick a component, install the package, and find every export of @mediansh/widget.
Install
@mediansh/widgetimport "@mediansh/widget/styles.css";Import the stylesheet once. The peer dependencies are react and react-dom
18 or 19, and convex 1.25 or newer below 2. The package is marked
"use client", so a Next.js server component can render it directly. Keys,
environment variables and CSP are on Install the widget.
Which component
| Component | Renders | Results go to | Without React |
|---|---|---|---|
MedianSupport | A launcher in the corner that opens a chat panel | A conversation in Inbox | mountMedianSupport() |
MedianSupportModal | The same launcher, with the panel centered over the page | A conversation in Inbox | mountMedianSupportModal() |
MedianContactForm | A form on your page with email, message and your own fields | Inbox. It joins the visitor's open conversation, or starts one | mountMedianContactForm() |
MedianFeedback | A note box that opens from your own trigger or from code | Signal, filed as a bug or a suggestion | mountMedianFeedback() |
Mount functions take the component's props as one object, plus a target for
the contact form. See Without React.
Keys
Every component takes one of two props.
| Prop | Value | Use it when |
|---|---|---|
apiKey | The median_pk_ id from publicKeyFromMedianKey(MEDIAN_KEY) | Visitors are anonymous, or you pass user yourself |
identity | The path of a route built with medianIdentity | Your session lives on the server. The route returns the key and the signed in user |
Pass both to render on apiKey at once and pick up the user when the route
answers. With neither, the component prints an error. See
Identity.
Shared rules
- Mount one support panel per page,
MedianSupportorMedianSupportModal. Two share one open state and open together. - Mount one
MedianFeedbackper page, for the same reason. Its open state is separate from the support panel's. - Components with the same key share one visitor. A chat message, a contact
form send and a feedback note from one browser belong to the same customer.
The browser keeps that visitor in
localStorage. - An error inside a component hides that component and prints to the console. Your page keeps running.
- Component text is in English, with no locale prop. The agent's reply language is on Built-in abilities.
- Colors come from your page's CSS variables. See Theming.
Exports
| Export | Kind | Documented on |
|---|---|---|
MedianSupport | Component | Support widget |
MedianSupportModal | Component | Support modal |
MedianContactForm | Component | Contact form |
MedianFeedback | Component | Feedback panel |
mountMedianSupport, mountMedianSupportModal, mountMedianContactForm, mountMedianFeedback | Function | Without React |
medianSupport, medianFeedback | Object | Control from code |
useMedianSupport, useMedianFeedback | Hook | Control from code |
useMedianContact | Hook | Contact form |
sendMedianContact | Function | Contact form |
reportError | Function | Crash reports |
useCanReportError | Hook | Crash reports |
| Type | Documented on |
|---|---|
MedianSupportProps, MedianUser, SupportLauncherKind | Support widget |
MedianSupportModalProps | Support modal |
MedianContactFormProps, MedianContactField, MedianContactFieldKind, MedianContactMessage, MedianContactOptions, MedianContactControl, UseMedianContactOptions | Contact form |
MedianFeedbackProps | Feedback panel |
MedianSupportControl, MedianFeedbackControl | Control from code |
MedianSupportInstance, MedianSupportModalInstance, MedianContactFormInstance, MedianContactFormMountOptions, MedianFeedbackInstance | Without React |
MedianErrorReportOptions, MedianErrorReportOutcome | Crash reports |
MedianDiagnostics | Context and diagnostics |
The Portal* names from @tryportal/widget, such as PortalSupport, still
work. They will be removed in a later major version.
Accessibility
The support panel and the modal handle these for you.
- Every icon button has a label, such as Close support and Send message.
- The launcher is labelled Chat with Acme support, plus the unread count when there is one.
- The thread is a
logregion witharia-live="polite", so new replies are announced. The unread card is a politestatusregion. - Agent avatars are announced by name.
- The closed panel is
inert, so nothing in it takes focus. - Escape closes the panel. Focus moves into the panel on open. On close it
returns to the launcher, or with
launcher="hidden"to the element that opened the panel.