For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
Log inSign up
Support
GuidesReferenceClick-to-Call
GuidesReferenceClick-to-Call
  • Getting Started
    • Overview
    • Authentication
    • RxJS Primer
    • Migrate from v3
  • Web Components
    • Overview
    • Click-to-Call
    • Theming
    • Customization
  • Build Voice & Video Apps
    • Overview
    • Outbound Calls
    • Inbound Calls
    • Device Management
    • Screen Sharing
    • Call Controls
    • Layouts
    • Messaging & Chat
  • Manage Resources
    • Overview
    • Users
    • Address Book
    • Client Preferences
    • Capabilities
  • Deploy
    • Overview
    • Framework Integration
    • SSR & Next.js
    • Troubleshooting
LogoLogoSignalWire Docs
Log inSign up
Support
On this page
  • Slots
  • Programmatic control
  • Pass-through attributes
  • Building from primitives
  • Provider contexts
  • Component events
  • Replacing a primitive
  • Choosing the right level
Web Components

Customization

|View as Markdown|Open in Claude|
Was this page helpful?
Edit this page
Previous

Overview

Next
Built with

When <sw-call-widget> doesn’t fit the layout, drop down to the primitives. The widget itself is built from the same elements, wired together through reactive contexts.

Three patterns, in increasing order of customization:

  1. Slots — keep <sw-call-widget>, replace one region (trigger or background).
  2. Events & methods — attribute / event / method API; the widget still owns the lifecycle.
  3. Primitives — drop the widget and compose <sw-call-provider>, <sw-call-media>, <sw-call-controls>, etc. directly.

Slots

<sw-call-widget> exposes a background slot for the full-bleed background and a default slot for the idle-state trigger. Anything in the default slot becomes the click target; clicking calls widget.dial().

1<sw-call-widget modal token="c2c_…" destination="/public/sales">
2 <sw-ui-background slot="background" default></sw-ui-background>
3
4 <button class="cta">
5 <svg><!-- your icon --></svg>
6 Talk to sales
7 </button>
8</sw-call-widget>

Once dialing starts the widget swaps into call mode (inline or modal, per the modal attribute).

Programmatic control

<sw-call-widget> exposes dial() and hangup() for driving dialing from JS instead of the trigger slot:

1const widget = document.querySelector("sw-call-widget");
2
3document.querySelector("#dial-btn").addEventListener("click", async () => {
4 try {
5 await widget.dial();
6 } catch (err) {
7 console.error("dial failed", err);
8 }
9});
10
11document.querySelector("#hangup-btn").addEventListener("click", () => {
12 widget.hangup();
13});

The widget bubbles sw-dial, sw-call-ended, and forwarded agent events:

1widget.addEventListener("sw-call-ended", (e) => {
2 analytics.track("call_ended", { status: e.detail.status });
3});

See <sw-call-widget> for the full event surface.

Pass-through attributes

Widget attributes toggle sub-features:

  • transcription — enables the AI transcript drawer.
  • allow-incoming-calls — listens for inbound calls on the same token.
  • audio-only — skips the camera.
  • user-variables — JSON string forwarded into the Verto invite for the receiving side to read.

See <sw-call-widget> for the full attribute list.

Building from primitives

For full layout control, compose the primitives directly. <sw-call-provider> is the only required wrapper — it owns the reactive contexts that the SDK-aware components subscribe to.

1<sw-call-provider id="provider">
2 <div class="my-grid">
3 <sw-call-media></sw-call-media>
4 <sw-self-media></sw-self-media>
5 <sw-call-status></sw-call-status>
6 <sw-call-controls show-screen-share show-fullscreen></sw-call-controls>
7 <sw-device-selector></sw-device-selector>
8 </div>
9</sw-call-provider>
10
11<script type="module">
12 import { SignalWire, StaticCredentialProvider } from "@signalwire/js";
13 import "@signalwire/web-components";
14
15 const client = new SignalWire(
16 new StaticCredentialProvider({ token: "YOUR_SAT" })
17 );
18
19 const call = await client.dial("/private/sales", { audio: true, video: true });
20
21 const provider = document.getElementById("provider");
22 provider.call = call;
23 provider.deviceController = client.deviceController;
24</script>

For the embed bundle, replace the imports with const { SignalWire, StaticCredentialProvider } = SignalWireUI; and drop <script type="module">.

Provider contexts

<sw-call-provider> mounts reactive contexts for call state, devices, transcript, and forwarded user events. Set .call and .deviceController; every nested SDK-aware element subscribes automatically. State changes (participant joins, device changes, transcript lines) push through the contexts to whichever components are listening.

Component events

Each primitive bubbles its own composed events: <sw-call-controls> emits sw-mute-audio / sw-mute-video / sw-hangup; <sw-call-dialpad> emits sw-digit-press; <sw-device-selector> emits sw-device-change. Events bubble across shadow DOM:

1provider.addEventListener("sw-hangup", () => {
2 // user clicked hangup — clean up app state
3});

Per-element event payloads are listed in the Web Components reference.

Replacing a primitive

Because components subscribe to context independently, a custom element that dispatches the same composed events is a drop-in replacement.

1<sw-call-provider .call="${call}">
2 <sw-call-media></sw-call-media>
3 <my-fancy-dialpad></my-fancy-dialpad> <!-- emits sw-digit-press -->
4 <sw-call-controls></sw-call-controls>
5</sw-call-provider>

SDK-aware components don’t talk to each other directly — they all go through the call object — so any element emitting the right events fits.

Choosing the right level

NeedUse
One call button on a page<sw-click-to-call>
Inline or modal call UI with default layout<sw-call-widget>
Same with a custom trigger or background<sw-call-widget> + slots
Custom layout, keep SDK-aware primitives<sw-call-provider> + primitives
No web componentsBrowser SDK directly

See Theming for the visual side and the Web Components reference for per-element attributes, slots, and events.