# Web SDK

Get creative! Below is an example of how DropContact use Birdie SDK

<figure><img src="/files/mz2UbR9PSy15jL4D5erh" alt=""><figcaption><p>Birdie Web SDK</p></figcaption></figure>

#### **1. Install Birdie Web SDK**

Go to [Settings → Integrations](https://app.birdie.so/settings/integrations#websdk) and scroll down to the Web SDK item, copy the snippet, and paste it before closing the <mark style="color:green;">`</body>`</mark> tag.

You webSDK snippet will look like the example below, all parameters are optional, but the more you can add the more context you will get 👌

```javascript
<script>
window.birdieSettings={
    app_id:"xxxxxxxx", // your identifier goes here
    /* Replace items below with your customer info, all optional */
    contact_name: "Alexander the Great",
    contact_email: "alex@empire.com",
    contact_id: "ebf45a994-32d28c4",
    tag: "frontpage" 
</script>
<script>(function(){window.addEventListener("load",function(){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src="https://app.birdie.so/widget/"+window.birdieSettings.app_id,document.body.appendChild(t)});})();</script>
```

{% hint style="info" %}
Tip: you can add more than one **tag** by separating them with a comma, e.g. \
`tag: "bug,frontpage,signup"` will add 3 different tags to your video: `bug`, `frontpage`, and `signup`.
{% endhint %}

#### **2. Create a custom launcher**

Simply add the classname <mark style="color:red;">`zstw_open`</mark> to one or multiple elements you want to use as a launcher, see 2 examples below:

```
<a href="#" class="zstw_open">Click here</a>
<button class="zstw_open">Open the widget if not already opened</button>
```

<details>

<summary>Handling the widget with Javascript</summary>

In some situations, you may prefer to use Javascript to control the widget opening. We provide a few methods for you to use:

• To check the widget status: <mark style="color:red;">`window.zest.widget.opened()`</mark> will return a boolean.&#x20;

• To open the widget: <mark style="color:red;">`window.zest.widget.open()`</mark> will open the widget if it is not already open.&#x20;

• To close the widget: <mark style="color:red;">`window.zest.widget.close()`</mark> will close the widget if it is not already closed.&#x20;

• To toggle open/close automatically: <mark style="color:red;">`window.zest.widget.toggle()`</mark>.

For example:

```javascript
<script>
function toggle_manual() {
    if (window.zest.widget.opened()) {
        window.zest.widget.close();
    } else {
        window.zest.widget.open();
    }
}
</script>`
```

</details>

<details>

<summary>Listening for events</summary>

You can hook into 5 different events:&#x20;

<mark style="color:red;">`onRecorderOpened`</mark>\ <mark style="color:red;">`onRecorderClosed`</mark>\ <mark style="color:red;">`onRecordingStarted`</mark>\ <mark style="color:red;">`onRecordingStopped`</mark>\ <mark style="color:red;">`onRecordingPosted`</mark> \
\
You must register them from the birdieSettings object, as shown into the example below:

```javascript
<script>
window.my_callback_recorder_opened = function() {
	console.log("The recorder popup has been opened")
	// you own code…
};
window.my_callback_recorder_closed = function() {
	console.log("The recorder popup has been closed")
	// you own code…
};
window.my_callback_recording_started = function() {
	console.log("The recording has just started")
	// you own code…
};
window.my_callback_recording_stopped = function() {
	console.log("The recording has just stopped")
	// you own code…
};
window.my_callback_recording_posted = function(link) {
	console.log("The recording was sent, the sharing link is:", link)
	// you own code can use the the sharing link given as parameter…
        // if you changed the birdieSettings autoclose_recorder value to true, 
        // at this point the recorder popup window will close.
};

window.birdieSettings = {
   // other settings…
   onRecorderOpened: my_callback_recorder_opened,
   onRecorderClosed: my_callback_recorder_closed,
   onRecordingStarted: my_callback_recording_started,
   onRecordingStopped: my_callback_recording_stopped,
   onRecordingPosted: my_callback_recording_posted,
   /* optionnally change this to true to make the recorder close automatically */
   autoclose_recorder: false 
};
</script>
```

</details>

<details>

<summary>React code example</summary>

```jsx
// BirdieButton.tsx

import React, { useCallback, useEffect } from 'react';
import firebase from 'api/firestore/rebase';
import styles from './styles.module.scss';

export const BirdieButton = () => {
	
	useEffect(() => {
		if (typeof window === 'undefined') return;
		if (window.innerWidth <= 768) return; // birdie doesn't work on mobile
		if (window.birdie) return; // prevent fetching on every new page if already exists
		
		const currentUser = firebase.auth().currentUser;
		window.birdieSettings = {
			app_id: '#######', // replace ####### with your own identifier found in settings page at https://app.birdie.so/settings/inapp  
			contact_name: currentUser?.displayName,
			contact_email: currentUser?.email,
			contact_id: currentUser?.uid,
		};
		const script = document.createElement('script');
		script.type = 'text/javascript';
		script.async = true;
		script.src = 'https://app.birdie.so/widget/' + window.birdieSettings.app_id;  
		document.body.appendChild(script);
	}, []);

	const handleClick = useCallback(() => {
		if (window.birdie.widget.opened()) {
			window.birdie?.widget.close();
		} else {
			window.birdie?.widget.open();
		}
	}, []);

	return (
		<button type="button" onClick={handleClick} className={styles.headerButton}>Feedback</button>
	);
};


// which requires this type wherever types are defined:

declare global {
	interface Window {
		birdie: {
			widget: {
				opened: () => boolean;
				open: VoidFunction;
				close: VoidFunction;
			};
		};
		birdieSettings: {
			app_id: string;
			contact_name?: string | null;
			contact_email?: string | null;
			contact_id?: string;
		};
	}
}
```

</details>

### Example: Add Birdie to a custom ticket form using the Web SDK

A common use case involves using the Web SDK to integrate Birdie into a custom ticket form. While you're free to get creative, here are three different ways Birdie could be added to the Active Campaign ticket form:

#### Option 1: Use an existing field

<figure><img src="/files/2BPRQEEnLHJUKVYsrkoK" alt=""><figcaption><p>Option 1 - A Birdie button has been added in the existing Description field </p></figcaption></figure>

<figure><img src="/files/dfKkGlyf5Y4YHo6lZ1eZ" alt=""><figcaption><p>Option 1 - The video link is automatically added to the Description text box</p></figcaption></figure>

#### Option 2: Create a new field

<figure><img src="/files/eVXMq3FMuplHf97rOZ7F" alt=""><figcaption><p>Option 2 - A Birdie button has been added to a new field that display a visible text box for the video URL</p></figcaption></figure>

<figure><img src="/files/TuB0hafCzeJ2OTGBixpf" alt=""><figcaption><p>Option 2 - The video link is automatically added to the field in a visible text box</p></figcaption></figure>

#### Option 3: Create a new hidden field

<figure><img src="/files/fdKSztne5A51EOJu60Bn" alt=""><figcaption><p>Option 3 - A Birdie button has been added to a new field. There is no visible text box for the video URL</p></figcaption></figure>

<figure><img src="/files/JpUxOBmlL3gayIxGtXPj" alt=""><figcaption><p>The video URL is not visible. The UI of the Birdie button has changed.</p></figcaption></figure>

It exists many more options... Your turn now.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.birdie.so/birdie-docs/request-screen-recordings/installation/web-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
