> 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/devtools-console-logs-and-network-requests.md).

# DevTools: Console Logs & Network Requests

Birdie DevTools for incoming screen recordings

{% hint style="info" %}
**Requirement**: The [Birdie snippet](broken://pages/7oW5RCmeXyrF2bozeaAi) must be installed on your web app

**Note**: Birdie collects logs only from your web app
{% endhint %}

## Why Console Logs and Network Requests Matter

For complex troubleshooting—such as when an issue can’t be replicated in your own environment—console logs and network requests provide invaluable insights. These logs allow your team to diagnose problems more effectively without relying on customers to manually open developer tools or send screenshots of their logs.\
\
Birdie collects:

* **Session and Device Metadata**: URL, Timestamp, Country, Device, Browser, Operating System
* **Console Logs**
* **Cookies**
* **Network Requests:** Fetch, XHR

## Prerequisite

#### Exclude Birdie from request interception / logging tools

If your application uses tools that intercept or monitor network requests (such as Service Workers, logging tools like Datadog, or custom request wrappers), make sure to **exclude Birdie endpoints** from those mechanisms.

**Affected endpoints:**  `*.birdie.so`

<details>

<summary><strong>More details</strong></summary>

Birdie relies on real-time network calls to:

* collect logs (console, network, user steps)
* send them reliably during a recording session

If these requests are:

* intercepted
* cached
* replayed
* or modified

…it can lead to issues such as:

* missing logs
* duplicated events
* delayed or out-of-order data

**Common sources of interference**

* **Service Workers** (e.g. Angular PWA `ngsw-worker`)
* **Network logging tools** (e.g. Datadog RUM, Sentry, etc.)
* **Custom fetch/XHR wrappers or proxies**
* **Offline/caching strategies**

**What to do**

Ensure that Birdie endpoints are **excluded from:**

* caching strategies
* retry/replay mechanisms
* request/response transformations

In most setups, this means adding a rule to **bypass interception for `*.birdie.so` requests**.

</details>

## Enabling Console Logs and Network Requests

* Ensure the [**Birdie snippet**](broken://pages/7oW5RCmeXyrF2bozeaAi) is installed on your web app.
* Make sure you [**identify your customer**](https://docs.birdie.so/birdie-docs/request-screen-recordings/installation/snippet#id-3.-identify-your-customer-with-an-email) with his email.
* [**Go to your Birdie**](https://app.birdie.so/settings) [Settings → Logs](https://app.birdie.so/settings/logs) and enable the collection of **Console Logs** and **Network Requests**.

<div><figure><img src="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FH8k3eBPzs0DINw25n5uc%2FSlice%2047.png?alt=media&amp;token=a0e0b0f4-3111-4a02-9163-5e278f7425fa" alt="" width="375"><figcaption><p>Capture console logs via Birdie</p></figcaption></figure> <figure><img src="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FZd2sirQragi8sksvijcR%2Fnetwork%20requests.png?alt=media&amp;token=87c8aa4d-139d-43ef-b72b-a402255c979f" alt="" width="375"><figcaption><p>Capture Fetch / HXR requests via Birdie</p></figcaption></figure></div>

Birdie also captures the cookies visible to the recorded page - a snapshot at the start of the recording plus any cookie added, changed or removed during the session (name, value, domain, path, expiry, `Secure`, `SameSite`). Secret-looking values are masked with `*****` before leaving the browser. [See *What if Birdie doesn't collect all the logs ?*](#what-if-birdie-doesnt-collect-all-the-logs) for what cookies can and can't be captured.

<br>

<details>

<summary>What if my user has more than 1 window open?</summary>

If more than one browser tab is open with your web app, we will always display the console logs coming from the latest active tab (or window). If the user switches tabs during a recording, the console will also switch to the new focused tab, and it will be notified in the console flow with a "Tab switch" event.

</details>

<details>

<summary>What if Birdie doesn't collect all the logs ?</summary>

Console log recording systems captures logs generated within the web page’s JavaScript context. However, certain logs that users see in the browser console may not be captured due to the following limitations:

1. **Browser and Extension Logs:** Logs generated by the browser itself (e.g., warnings, deprecation notices) or by browser extensions (e.g., ad blockers, developer tools) are beyond the scope of our page-level JavaScript and cannot be intercepted.&#x20;
2. **Cross-Origin Restrictions:** Logs from scripts loaded from other origins may be restricted by browser policies (like CORS), making them inaccessible for security reasons.
3. **Direct Browser Logs:** Some browser-level errors, like network failures (`net::ERR_BLOCKED_BY_CLIENT`), are directly logged by the browser to the console and do not pass through JavaScript `console` methods, meaning they cannot be recorded by our system.
4. **Cookies:** Only cookies the page's own JavaScript can read are captured - i.e. the site's own, non-**HttpOnly** cookies. **HttpOnly** cookies, and cookies belonging to third parties or other subdomains, are hidden from page scripts and can't be recorded. Available cookie details also depend on the browser: **Chromium** (Chrome, Edge) exposes full metadata, while **Firefox** doesn't report `Secure`, `SameSite` or expiry (shown as "unknown").

These limitations are inherent to browser security models and cannot be bypassed by standard JavaScript execution within the web page. \
💡 For more info, refer to the page: [How to improve Logs Capture with Birdie](/birdie-docs/request-screen-recordings/devtools-console-logs-and-network-requests/how-to-improve-logs-capture-with-birdie.md)

</details>

<details>

<summary>Why is a network response empty or missing?</summary>

Every request your app makes during the recording is listed, with its URL, method, status, headers and timing. The **response body** is shown only when Birdie can read it safely, so some rows have no body. That happens when:

* **The request goes to another domain.** Bodies are read only for requests to the same domain as the page: `app.acme.com` calling `api.acme.com` works, a call to a third-party API or to your own API on a separate domain does not. This is a privacy rule. Serving your API under the same domain as your app makes the bodies appear.
* **The response is not text.** Birdie reads text, JSON, XML and form-encoded responses. Images, PDFs, downloads and binary formats are skipped, as are JSON responses sent without a `Content-Type` header or as `application/octet-stream`.
* **The response is streamed or opaque.** Server-sent events, streamed answers, `no-cors` requests, and XHR requests that return a blob or buffer cannot be read without disturbing your app, so Birdie leaves them alone.
* **The request started before the recording.** A request already in flight when the recording began, or one sent by a service worker, `sendBeacon` or an iframe, is known only from the browser's timing data. It shows status `0` or `Unknown`, with no headers and no body.
* **There is no body.** `204`, `304` from cache, redirects, `HEAD` requests, and requests the browser blocked or that failed have nothing to show.
* **It is a script file.** Bodies of `.js` files are never stored.

Two cases look different but are expected:

* If response-body masking is on, the body reads `Request body not captured - privacy settings`. See *What Happens to Sensitive Data in Network Requests?* above.
* Bodies over 128 KB are cut and end with `[Body truncated over the 128KB limit]`.

{% hint style="info" %}
A request is missing from the list entirely when it happened in a browser tab that does not run the Birdie snippet, for example a login page served by a different app.
{% endhint %}

</details>

<details>

<summary>What Happens to Sensitive Data in Network Requests?</summary>

At Birdie, we understand that network requests may contain sensitive information—such as tokens, cookies, or personal data. That’s why we’ve designed our system with privacy and security as a top priority.

#### Client-Side Filtering

When Birdie captures network requests during a screen recording, we proactively **scan and sanitize all requests on the client side**. This means any potentially sensitive data is removed *before* it ever reaches our servers.

Specifically:

* We filter out sensitive fields from **request headers**.
* If the request body is in **JSON format**, we scan and sanitize it as well.

This ensures that sensitive values such as Bearer and JWT tokens, api keys, credit card numbers, etc. are never saved to Birdie’s backend.

#### What You’ll See in Birdie

In your Birdie recording, any fields that were flagged as sensitive will masked with `***************`

<figure><img src="https://3843507234-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FECPgvsGwy5oMz4WIZw3a%2Fuploads%2FM1I0FBYe4YGB4IBrJsJ8%2Fsecurity%20network%20request.png?alt=media&amp;token=af7e0603-1c28-4266-8547-6654dc3d3ad6" alt=""><figcaption><p>Example of Sensitive Data Masked in Network Headers</p></figcaption></figure>

This indicates that we’ve scrubbed the original value for security reasons. Filtering happens *before* the recording is uploaded, so no unfiltered data ever leaves the device.

#### A Cautious Approach

We believe it's better to **over-filter than under-filter**. As a result, you might occasionally see information masked that isn’t truly sensitive. If you notice something that could be improved, we’d love your feedback—just reach out to us at <security@birdie.so>.

#### Custom Keys

You can add your own custom keys to hide [in your Security Settings page](https://app.birdie.so/settings/security). \
Please note these keys are case-insensitive, and must be separated by commas.&#x20;

#### How to exclude Response bodies?

As an additional security layer you may want to exclude every Response body from the collected logs. If you want to go this way add this settings block when you initialize Birdie:

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

initBirdie({
  clientId: "YOUR_CLIENT_ID", // required
  metadata: { /* your stuff, see installation examples */ }, // optional
  
  settings: { // Add this block 
    privacy: {
      mask_response_body: true
    }
  },
  
  onReady(birdie) { /* your stuff, see installation examples */ } // optional
});
```

</details>
