Skip to main content
Every notable element rendered by the widget carries a stable data-ringg="<name>" attribute, and state-bearing elements carry additional data-ringg-<state> attributes that update as the widget changes state. Use them as CSS selectors or JS query targets to restyle, hide, rearrange, or script the widget.
Do not target the internal ringg_ai-* class names. They are minified output and change between releases. Style and script the widget through data-ringg attributes only.

Quick example

State attributes

State-bearing elements expose additional data-ringg-<state> attributes. They update live, so you can drive CSS off them with attribute selectors or watch them with MutationObserver. Compound selector example:
Observer example:

Element reference

Elements are grouped by where they appear in the widget.

Top level

Call controls (audio mode)

Compact centered mute/end pair, no text labels, since icons carry the meaning.

Action buttons (start screen)

The start screen shows both buttons side by side (Chat left, Call right), each starting its mode directly. With hideTabSelector: true only the defaultTab mode’s button renders, full-width.

Loading bar

Quick replies and options

Quick-reply chips (free presentation) and boxed option lists rendered below an agent message.

Typing indicator

Shown while an agent reply is pending. Cycles through words (default: Thinking / Reasoning / Working on it / Almost there; override with the typingWords config) each rendered with a left→right text shimmer.

Messages

System log pill

The system log pill renders the inline activity feed in the transcript. It only shows up when you opt in via loadAgent({ eventLogs: { enabled: true } }). See Agent actions for details.

Slash command menu

Voice animation

data-ringg-lit updates at audio rate. Keep CSS transitions on it lightweight, for example transition: opacity 50ms. Heavy transitions or expensive observers on this attribute will fire every frame.

Interactive flow

Message input (text mode)

Feedback screen

When the ended conversation has text messages, the transcript stays readable and the rating renders as a footer below it (data-ringg-variant="transcript"); tapping a star submits immediately. The legacy centered card (comment box + submit/skip) renders when there is no transcript. Transcript variant Legacy centered card

Components

Block trees the agent streams on the ringg.blocks topic: the cards, forms and pickers built under Embed & Widgets → Components (see Components). Rendered full-width in the transcript.

End-call confirm dialog

The end-call confirm dialog renders in a portal outside [data-ringg="widget-root"]. Scope its selectors at the document level.

Common recipes

Restyle the launcher

Style the muted state

Glow on lit visualizer dots

Italicize agent messages

Wait for the widget to mount

Capture feedback submissions

For lifecycle hooks like open/close, conversation start/end, and the feedback payload itself, listen to the events documented in Widget Lifecycle Events. Use data-ringg attributes for UI affordances the widget does not surface as events.

QA notes

All your selectors target [data-ringg="..."] attributes, not internal ringg_ai-* class names.
Compound selectors with state attributes (for example [data-ringg="mute-button"][data-ringg-muted="true"]) update live as the widget changes state.
Selectors for the end-call confirm dialog are document-scoped, not nested under [data-ringg="widget-root"].
CSS transitions on [data-ringg-lit] are lightweight, so per-frame state changes do not cause jank.