> For the complete documentation index, see [llms.txt](https://docs.birdie.so/birdie-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.birdie.so/birdie-docs/request-screen-recordings/installation/web-sdk.md).

# Web SDK

Open Birdie recorder from a specific button, link or element in your web app!

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

<figure><img src="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FcZrnrJm3ACQ62vDgilet%2FBirdieSDK.gif?alt=media&amp;token=c3052f6f-e652-42da-8d81-0767a063aa66" alt=""><figcaption><p>Birdie Web SDK</p></figcaption></figure>

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

{% hint style="info" %}
Using a framework? Go to [install with npm](#install-with-npm)
{% endhint %}

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 async src="https://cdn.birdie.so/websdk/index.js"></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 %}

#### Install with npm&#x20;

> Available from `@birdie-so/snippet@1.3.1`

If your app already uses `@birdie-so/snippet`, or you prefer a package over a script tag, the launcher is one option away:

```bash
npm install @birdie-so/snippet
```

{% code overflow="wrap" %}

```javascript
import { initBirdie } from "@birdie-so/snippet";

initBirdie({
  clientId: "xxxxxxxx",
  contact: { 
    id: "ebf45a994-32d28c4", 
    name: "Alexander the Great", 
    email: "alex@empire.com" 
  },

  launcher: true,
  // or: launcher: { trigger: "#record-button", tag: "frontpage", autoClose: true }

  onReady(birdie) {
    birdie.on("recorderOpen",  () => console.log("recorder window opened"));
    birdie.on("start",         () => console.log("recording started"));
    birdie.on("stop",          () => console.log("recording stopped"));
    birdie.on("recordingSent", (data) => console.log("sharing link:", data.link));
    birdie.on("recorderClose", () => console.log("recorder window closed"));
  },
});
```

{% endcode %}

`launcher: true` loads the Web SDK next to the snippet. Without it, nothing launcher-related is loaded. On phones and tablets nothing is loaded at all, and `birdie.launcher.open()` emits an `error` event instead.

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

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

```html
<a href="#" class="birdieWebsdk_open">Click here</a>
<button class="birdieWebsdk_open">Open the recorder if not already opened</button>
```

The recorder opens in its own window the moment the element is clicked. While it is open, Safari shows a small ‘Recorder open’ chip at the bottom right of your page to bring the window back; other browsers show Birdie’s floating recording controls instead.

<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.birdie.launcher.opened()`</mark> will return a boolean.&#x20;

• To open the recorder: <mark style="color:red;">`window.birdie.launcher.open()`</mark> opens the recorder window if it is not already open.

• To close the recorder: <mark style="color:red;">`window.birdie.launcher.close()`</mark> closes the recorder window; <mark style="color:red;">`closeRecorder()`</mark> is the same call under the name the npm package types use.

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

For example:

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

{% hint style="info" %}
`open()` opens a browser window, so call it from a user action such as a click handler. Called from a timer or on page load, the browser blocks it and Birdie emits an `error` event with `popup_blocked`.
{% endhint %}

</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.

{% hint style="info" %}
With the npm package, the same five events are available through `birdie.on()`: `recorderOpen`, `recordingSent`, `start`, `stop` and `recorderClose`; `recordingSent` receives `{ link }`.
{% endhint %}

```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>

Install the package once:

```bash
npm install @birdie-so/snippet
```

Then initialize Birdie where your app knows the current user, and open the recorder from any button:

```tsx
// BirdieButton.tsx
import { useEffect } from "react";
import { initBirdie, getBirdieInstance } from "@birdie-so/snippet";
import { useCurrentUser } from "./auth"; // whatever gives you the signed-in user

export function BirdieButton() {
  const user = useCurrentUser();

  useEffect(() => {
    initBirdie({
      clientId: "xxxxxxxx", // your identifier, from Settings → Integrations → Web SDK
      contact: {
        id: user?.id,
        name: user?.displayName,
        email: user?.email,
      },
      launcher: true, // loads the recorder launcher next to the snippet

      onReady(birdie) {
        birdie.on("recordingSent", (data) => {
          // data.link is the sharing link of the new recording
          console.log("Recording sent:", data.link);
        });
      },
    });
  }, [user?.id]);

  function handleClick() {
    // open() must run from a user action: it opens the recorder window
    getBirdieInstance()?.launcher?.open();
  }

  return (
    <button type="button" onClick={handleClick}>
      Record your screen
    </button>
  );
}
```

Notes:

* `initBirdie()` is safe to call more than once: scripts are injected a single time.
* `getBirdieInstance()` returns `null` until Birdie is ready, so the optional chaining above is enough; no device check is needed, on phones and tablets the package provides an inert `launcher` and emits an `error` event instead of opening anything.
* Call `launcher.open()` from a click handler, as here. Called from a timer or on mount, the browser blocks the recorder window.
* Already loading the snippet with `initBirdie()` elsewhere in your app? Add `launcher: true` to that call instead of calling it again here.

</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="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FuVgajQfPVOakqfxQR5jx%2FSlice%20129.png?alt=media&amp;token=fea97a03-8d8a-4420-8328-196e37b5da94" alt=""><figcaption><p>Option 1 - A Birdie button has been added in the existing Description field </p></figcaption></figure>

<figure><img src="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FxWgwrNPXWOknJqZaqpuH%2FSlice%20130.png?alt=media&amp;token=df2a1cef-a3e7-472f-945c-d00954a9f99c" 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="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FeR15Ndyj8r9C2UzalSaG%2FSlice%20131.png?alt=media&amp;token=997393d5-6b70-4697-a649-fc32ed8b119f" 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="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FU6UNryDGfgKPXz71O4xi%2FSlice%20132.png?alt=media&amp;token=b6788730-e63e-48dd-8acc-a195042bc96e" 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="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FA2akOnFT2ivE3ainyimo%2FSlice%20133.png?alt=media&amp;token=e26d3c05-c07d-4610-895d-c94835ed9600" 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="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FuiDliikeBViT6AAhFSUX%2FSlice%20134.png?alt=media&amp;token=c1b7fb41-11d4-41ff-af55-6902e0c48b89" 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.
