---
title: "CDN / स्क्रिप्ट टैग"
description: "बंडलर के बिना किसी भी वेबसाइट में ThunderPhone वॉइस विजेट जोड़ें"
---

CDN बिल्ड React को आंतरिक रूप से बंडल करता है, इसलिए आप विजेट को स्टैटिक साइटों, WordPress, Webflow, या किसी भी ऐसे पेज पर उपयोग कर सकते हैं जहाँ आप HTML जोड़ सकते हैं। npm, बंडलर या फ्रेमवर्क की आवश्यकता नहीं है।

## CDN URLs

<CodeGroup>
```html Latest (recommended)
<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
```

```html Pinned version
<!-- Each stable release also publishes an immutable /widget/vX.Y.Z/ path
     matching the @thunderphone/widget npm version (v1.1.2 at the time of
     writing). If you pin, you own updating the URL for new releases. -->
<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/v1.1.2/style.css" />
<script src="https://cdn.thunderphone.com/widget/v1.1.2/widget.js"></script>
```
</CodeGroup>

<Tip>
  `latest` URLs वे हैं जिन्हें डैशबोर्ड का एम्बेड स्निपेट जनरेटर बनाता है। इन्हें 5 मिनट के लिए कैश किया जाता है और ये नई स्टेबल रिलीज़ को स्वचालित रूप से प्राप्त करते हैं। पिन किए गए `/widget/vX.Y.Z/` पाथ अपरिवर्तनीय होते हैं और लंबे समय के लिए कैश किए जाते हैं -- यदि आप पिन करते हैं, तो वर्शन को उस `@thunderphone/widget` npm रिलीज़ से मिलाएँ जिसके विरुद्ध आप डेवलप करते हैं।
</Tip>

---

## बुनियादी उपयोग

```html
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
</head>
<body>

  <div id="thunderphone"></div>

  <script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
  <script>
    ThunderPhone.mount({
      element: '#thunderphone',
      publishableKey: 'pk_live_your_publishable_key',
    })
  </script>

</body>
</html>
```

विजेट लक्ष्य एलिमेंट में माउंट होता है और **व्यूपोर्ट के किसी कोने में फिक्स्ड-पोज़िशन बार** के रूप में रेंडर होता है (डिफ़ॉल्ट `bottom-right`, जिसे `position` विकल्प नियंत्रित करता है)। माउंट एलिमेंट केवल React रूट है -- पेज में उसका स्थान विजेट के दिखाई देने की जगह को प्रभावित नहीं करता।

---

## माउंट विकल्प

`ThunderPhone.mount()` React कंपोनेंट जैसे ही विकल्प स्वीकार करता है, साथ ही `element` प्रॉपर्टी भी:

| विकल्प | प्रकार | आवश्यक | डिफ़ॉल्ट | विवरण |
|--------|------|----------|---------|-------------|
| `element` | `string \| HTMLElement` | हाँ | -- | CSS सेलेक्टर (उदाहरण के लिए, `'#thunderphone'`) या DOM एलिमेंट रेफ़रेंस। |
| `publishableKey` | `string` | हाँ | -- | पब्लिश करने योग्य API key (`pk_live_...`)। एजेंट को key के विजेट कॉन्फ़िगरेशन से स्वचालित रूप से निर्धारित किया जाता है। |
| `theme` | `'light' \| 'dark'` | नहीं | `'light'` | कलर स्कीम। |
| `primaryColor` | `string` | नहीं | `'#000000'` (लाइट) / `'#ffffff'` (डार्क) | एक्सेंट कलर के रूप में इस्तेमाल की जाने वाली CSS कलर स्ट्रिंग। |
| `title` | `string` | नहीं | `'Voice assistant'` | विजेट बार में दिखाया जाने वाला टेक्स्ट। |
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | नहीं | `'bottom-right'` | फिक्स्ड व्यूपोर्ट पोज़िशन। |
| `apiBase` | `string` | नहीं | `'https://api.thunderphone.com/v1'` | API बेस URL ओवरराइड। |
| `language` | `string` | नहीं | -- | प्रति-सेशन भाषा ओवरराइड -- `en`, `es`, या `fr-FR` जैसे भाषा कोड या लोकेल। सेट न होने पर, एजेंट की कॉन्फ़िगर की गई भाषा लागू होती है। key के [ब्राउज़र ओवरराइड](/hi/guides/embed-web-widget) में `language` आवश्यक है। |
| `voice` | `string` | नहीं | -- | प्रति-सेशन वॉइस ओवरराइड -- `maria` जैसा वॉइस नाम। सेट न होने पर, एजेंट की कॉन्फ़िगर की गई वॉइस लागू होती है। key के [ब्राउज़र ओवरराइड](/hi/guides/embed-web-widget) में `voice` आवश्यक है। |
| `context` | `string` | नहीं | -- | एजेंट को भेजा जाने वाला प्रति-सेशन तथ्यात्मक पेज या साइट कॉन्टेक्स्ट। सर्वर-साइड पर 12,000 वर्णों तक सीमित किया जाता है। key के [ब्राउज़र ओवरराइड](/hi/guides/embed-web-widget) में `context` आवश्यक है। |
| `onConnect` | `() => void` | नहीं | -- | वॉइस सेशन कनेक्ट होने पर कॉल किया जाता है। |
| `onDisconnect` | `() => void` | नहीं | -- | सेशन समाप्त होने पर कॉल किया जाता है। |
| `onError` | `(error) => void` | नहीं | -- | एरर होने पर कॉल किया जाता है। एरर में `error` (कोड) और `message` फ़ील्ड होते हैं। |
| `ringtone` | `boolean \| string` | नहीं | `false` | कनेक्ट करते समय रिंगटोन चलाएँ। डिफ़ॉल्ट रिंगटोन के लिए `true`, या कस्टम ऑडियो के लिए URL स्ट्रिंग। |

---

## क्लीनअप

`ThunderPhone.mount()` क्लीनअप मेथड्स के साथ एक विजेट इंस्टेंस लौटाता है:

```html
<script>
  var widget = ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
  })

  // Later, when you want to remove the widget:
  widget.unmount()

  // Or equivalently:
  widget.destroy()
</script>
```

`unmount()` और `destroy()` दोनों एक ही काम करते हैं -- वे किसी भी सक्रिय वॉइस सेशन को डिस्कनेक्ट करते हैं और विजेट को DOM से हटाते हैं। अपने कोड में जो बेहतर लगे, उसका उपयोग करें।

<Note>
  सिंगल-पेज एप्लिकेशन में दूसरे पेज पर नेविगेट करते समय या कंटेनिंग एलिमेंट हटाए जाने पर हमेशा विजेट को क्लीन अप करें। इससे सक्रिय वॉइस सेशन सही तरीके से डिस्कनेक्ट होते हैं।
</Note>

---

## उदाहरण

### कस्टम रंग के साथ डार्क थीम

```html
<div id="thunderphone"></div>

<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
    theme: 'dark',
    primaryColor: '#8b5cf6',
    title: 'Talk to our AI',
  })
</script>
```

### कस्टम पोज़िशन

```html
<div id="thunderphone"></div>

<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
    position: 'bottom-left',
  })
</script>
```

### इवेंट कॉलबैक के साथ

```html
<div id="thunderphone"></div>

<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
    onConnect: function () {
      console.log('Call started')
    },
    onDisconnect: function () {
      console.log('Call ended')
    },
    onError: function (error) {
      console.error('Widget error:', error.error, error.message)
    },
  })
</script>
```

### रिंगटोन के साथ

```html
<div id="thunderphone"></div>

<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  ThunderPhone.mount({
    element: '#thunderphone',
    publishableKey: 'pk_live_your_publishable_key',
    ringtone: true, // or a custom URL: 'https://example.com/ringtone.mp3'
  })
</script>
```

### DOM एलिमेंट रेफरेंस का उपयोग

```html
<div id="thunderphone"></div>

<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>
<script>
  var container = document.getElementById('thunderphone')

  ThunderPhone.mount({
    element: container,
    publishableKey: 'pk_live_your_publishable_key',
  })
</script>
```

### WordPress / CMS इंटीग्रेशन

इसे कस्टम HTML ब्लॉक या अपनी थीम के फ़ूटर में जोड़ें:

```html
<link rel="stylesheet" href="https://cdn.thunderphone.com/widget/latest/style.css" />
<script src="https://cdn.thunderphone.com/widget/latest/widget.js"></script>

<div id="thunderphone-widget"></div>
<script>
  ThunderPhone.mount({
    element: '#thunderphone-widget',
    publishableKey: 'pk_live_your_publishable_key',
  })
</script>
```

<Tip>
  `<div>` कहीं भी रखा जा सकता है -- यह केवल माउंट पॉइंट है। विजेट स्वयं व्यूपोर्ट के एक कोने में फिक्स्ड ओवरले के रूप में रेंडर होता है (`position` विकल्प द्वारा सेट) और आसपास के कंटेंट के साथ फ्लो नहीं करता।
</Tip>

---

## समस्या निवारण

<AccordionGroup>
  <Accordion title="Widget दिखाई नहीं दे रहा है">
    सुनिश्चित करें कि CSS और JS, दोनों फ़ाइलें लोड हैं। नेटवर्क त्रुटियों के लिए ब्राउज़र कंसोल जांचें। `ThunderPhone.mount()` कॉल करने से पहले सत्यापित करें कि लक्ष्य एलिमेंट DOM में मौजूद है।
  </Accordion>

  <Accordion title="ThunderPhone परिभाषित नहीं है">
    स्क्रिप्ट अभी तक लोड नहीं हुई है। सुनिश्चित करें कि `widget.js` के लिए `<script>` टैग आपकी माउंट कॉल से पहले दिखाई दे, या माउंट कॉल को `DOMContentLoaded` लिस्नर में रैप करें।
  </Accordion>

  <Accordion title="डोमेन की अनुमति नहीं है त्रुटि">
    [app.thunderphone.com](https://app.thunderphone.com) पर **वेब विजेट्स** पेज में अपने डोमेन को विजेट के अनुमत डोमेनों में जोड़ें। प्रोडक्शन में `localhost` को स्वचालित रूप से अनुमति नहीं मिलती; स्थानीय रूप से परीक्षण करने के लिए इसे सूची में जोड़ें।
  </Accordion>
</AccordionGroup>

---

## अगले चरण

<CardGroup cols={2}>
  <Card title="स्टाइलिंग" icon="palette" href="/hi/widget/styling">
    CSS कस्टम प्रॉपर्टीज़ के साथ widget का स्वरूप कस्टमाइज़ करें।
  </Card>
  <Card title="React कंपोनेंट" icon="react" href="/hi/widget/react">
    React का उपयोग कर रहे हैं? कंपोनेंट इंटीग्रेशन अधिक सरल है।
  </Card>
</CardGroup>
