Skip to main content

Embed a Voice Widget on Your Website

The Truedy embed widget lets anyone add a live AI voice call button to their website with a single <script> tag. Visitors click the button and speak directly to your Truedy AI agent in real time — no phone number, no app download, no backend required.
This guide covers the pre-built Truedy widget — the fastest way to go live. If you need full control over the UI and want to build a completely custom widget from scratch, see the Custom Voice Widget guide instead.

How it works

Visitor clicks widget button

       ├─ Widget JS requests a call session
       │     POST https://api.truedy.ai/api/v1/widgets/call?widget_id=xxx

       ├─ Truedy validates the widget & returns a WebRTC joinUrl

       └─ Browser connects directly to your Truedy agent via WebRTC audio
              (live, low-latency, two-way voice)
There is no API key exposed in your frontend — the widget authenticates via your Widget ID, and domain restrictions protect against misuse.

Step 1 — Create a widget in the dashboard

  1. Go to app.truedy.aiWidgets in the sidebar
  2. Click Create Widget
  3. Configure your widget:
    • Agent — which AI agent answers calls from this widget
    • Display name & subtext — shown to visitors
    • Primary colour — matches your brand
    • Avatar — upload a profile image (displayed when the agent is idle)
    • Speaking avatar — optional image shown when the agent is talking
    • Widget style — Bubble (floating FAB), Pill, or Side Tab
    • Position — bottom-right or bottom-left
    • Placement mode — Overlay (floating) or Embedded (inline in your page)
    • Allowed domains — restrict which websites can use this widget (recommended)
  4. Click Save

Step 2 — Copy the embed code

After saving, the widget builder shows your embed snippet in the Embed Code panel. Copy it — it looks like this: Overlay mode (floating button):
<!-- Truedy™ Voice Widget -->
<script src="https://api.truedy.ai/widget.js"></script>
<script>
  TruedyWidget.init({
    "widgetId": "YOUR_WIDGET_ID",
    "agentId": "YOUR_AGENT_ID",
    "agentName": "AI Assistant",
    "agentSubtext": "Live AI Voice Assistant",
    "primaryColor": "#6366f1",
    "position": "bottom-right",
    "buttonText": "Talk to AI",
    "darkMode": false
  });
</script>
Embedded mode (inline in your page):
<!-- Truedy™ Voice Widget - Embedded -->
<div data-truedy-embed="YOUR_WIDGET_ID" style="width:100%"></div>
<script src="https://api.truedy.ai/widget.js"></script>
<script>
  TruedyWidget.init({
    "widgetId": "YOUR_WIDGET_ID",
    "agentId": "YOUR_AGENT_ID",
    "placementMode": "embedded",
    "embeddedJustification": "center"
  });
</script>

Step 3 — Paste it on your website

Paste the embed snippet just before the closing </body> tag on any page where you want the widget to appear. HTML site:
    <!-- your page content -->

    <!-- Truedy™ Voice Widget -->
    <script src="https://api.truedy.ai/widget.js"></script>
    <script>
      TruedyWidget.init({ "widgetId": "YOUR_WIDGET_ID", ... });
    </script>
  </body>
</html>
WordPress: Paste in Appearance → Theme Editor → footer.php, or use a plugin like Insert Headers and Footers. Webflow: Go to Project Settings → Custom Code → Footer Code. Framer / Squarespace / Wix: Use the site-wide custom code or script injection setting. React / Next.js: Use next/script or a useEffect to load the script:
// app/layout.tsx (Next.js App Router)
import Script from 'next/script'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Script src="https://api.truedy.ai/widget.js" strategy="afterInteractive" />
        <Script id="truedy-init" strategy="afterInteractive">{`
          TruedyWidget.init({
            widgetId: "${process.env.NEXT_PUBLIC_TRUEDY_WIDGET_ID}",
            agentId: "${process.env.NEXT_PUBLIC_TRUEDY_AGENT_ID}"
          });
        `}</Script>
      </body>
    </html>
  )
}

Configuration reference

All options passed to TruedyWidget.init():

Identity

OptionTypeDefaultDescription
widgetIdstringRecommended. Your widget’s UUID from the dashboard. Loads all saved settings automatically.
agentIdstringYour agent’s UUID. Required alongside widgetId.

Display

OptionTypeDefaultDescription
agentNamestring"AI Assistant"Name shown in the widget header
agentSubtextstring"Live AI Voice Assistant"Subtitle shown below the name
primaryColorstring"#6366f1"Brand colour (6-digit hex, e.g. #FF5733)
buttonTextstring"Talk to AI"Label on the trigger button
profilePictureUrlstringAvatar image URL (shown when idle)
speakingPictureUrlstringAvatar image URL shown when agent is speaking
fontFamilystring"Inter, sans-serif"CSS font-family for the widget UI
darkModebooleanfalseEnable dark theme

Layout & Position

OptionTypeDefaultDescription
position"bottom-right" | "bottom-left""bottom-right"Corner for the floating widget
size"small" | "medium" | "large""medium"Size of the trigger button
placementMode"overlay" | "embedded""overlay"Floating overlay or inline in your layout
embeddedJustification"left" | "center" | "right""center"Alignment when placementMode is "embedded"

Behaviour

OptionTypeDefaultDescription
showPostCallRecapbooleanfalseShow a transcript summary after the call ends
speakingAnimationbooleantrueAnimate the avatar with a pulse when the agent speaks
autoOpenbooleanfalseAutomatically open the widget panel on page load
allowedDomainsstring[]Restrict the widget to specific domains (e.g. ["mysite.com", "*.mysite.com"])

Lock your widget to your own domains so it cannot be used on other sites. Set allowed domains either in the dashboard UI or in the allowedDomains config option:
TruedyWidget.init({
  widgetId: "YOUR_WIDGET_ID",
  agentId: "YOUR_AGENT_ID",
  allowedDomains: ["mysite.com", "*.mysite.com"]
});
Wildcards (*.mysite.com) match all subdomains. The check runs both client-side (blocks render) and server-side (blocks call creation), so it cannot be bypassed.

Embedded mode

To place the widget inline inside your page layout rather than as a floating overlay, use placementMode: "embedded" and add a <div> target:
<!-- Place this where you want the widget to appear -->
<div data-truedy-embed="YOUR_WIDGET_ID" style="width:100%; max-width:400px;"></div>

<script src="https://api.truedy.ai/widget.js"></script>
<script>
  TruedyWidget.init({
    widgetId: "YOUR_WIDGET_ID",
    agentId: "YOUR_AGENT_ID",
    placementMode: "embedded",
    embeddedJustification: "center"
  });
</script>
The widget renders inside the div, inheriting its width. Use CSS to control size and positioning.

Programmatic control

You can trigger the widget from your own buttons or application logic:
// Start a call immediately (e.g. from a custom CTA button)
TruedyWidget.start()

// End the active call
TruedyWidget.end()

// Remove the widget from the page entirely (useful in SPAs)
TruedyWidget.destroy()
Example — trigger from your own button:
<button onclick="TruedyWidget.start()">Talk to our AI</button>

<script src="https://api.truedy.ai/widget.js"></script>
<script>
  TruedyWidget.init({
    widgetId: "YOUR_WIDGET_ID",
    agentId: "YOUR_AGENT_ID",
    autoOpen: false
  });
</script>

React / SPA lifecycle cleanup

When using the widget in a single-page app, call destroy() to clean up when the component unmounts:
import { useEffect } from 'react'

export function VoiceWidget() {
  useEffect(() => {
    const script = document.createElement('script')
    script.src = 'https://api.truedy.ai/widget.js'
    script.onload = () => {
      window.TruedyWidget?.init({
        widgetId: process.env.NEXT_PUBLIC_TRUEDY_WIDGET_ID,
        agentId: process.env.NEXT_PUBLIC_TRUEDY_AGENT_ID,
      })
    }
    document.body.appendChild(script)

    return () => {
      window.TruedyWidget?.destroy()
    }
  }, [])

  return null
}

Post-call transcript

Enable showPostCallRecap: true to automatically show the visitor a summary of the conversation after the call ends. This is useful for support or sales contexts where the visitor wants a record.
TruedyWidget.init({
  widgetId: "YOUR_WIDGET_ID",
  agentId: "YOUR_AGENT_ID",
  showPostCallRecap: true
});
To receive transcripts on your server (for CRM logging, follow-ups, etc.), set up a webhook — Truedy sends a call.ended event with the full transcript when each call finishes.

Troubleshooting

Widget doesn’t appear
  • Check browser console for errors
  • Ensure the script URL is correct: https://api.truedy.ai/widget.js
  • Confirm widgetId and agentId are valid UUIDs
“Domain not allowed” — widget blocked
  • Your current domain is not in the widget’s allowedDomains list
  • Add your domain in the dashboard under Widgets → Edit → Allowed Domains, or remove the restriction entirely during development
“Microphone access denied”
  • The page must be served over HTTPS (or localhost) — browsers block mic access on plain HTTP
  • The visitor must grant microphone permission when prompted
Agent doesn’t respond / call drops immediately
  • Verify your agent is set to Active in the dashboard
  • Check that the agent has been saved and synced (a spinner may appear briefly after creation)
Call works but no audio
  • Ensure the visitor hasn’t muted the browser tab
  • Some corporate networks block WebRTC — this is outside Truedy’s control

Next steps