# Set up a custom recording domain

Connecting a custom domain allows Jam to:

* Serve recording links from your domain
* Capture console logs and network requests
* Attach developer logs directly to Jams
* Support Intercom-requested Jams

Without a custom domain, screen recordings will still work, but developer logs will not be included.

{% hint style="info" %}
You'll need write permissions to your website to complete these three steps:

1. **Set up Jam's Recorder & Capture Scripts** on your site *(so your users can start recording & capturing page context)*
2. **Register one custom domain URL** with Jam *(so we can generate links to your site)*
3. **Modify your Content-Security-Policy** if necessary *(so Jam assets can execute on your page)*
   {% endhint %}

## Set up your custom domain

### 1. Install Recorder & Capture Scripts

{% hint style="info" %}
To properly associate your users' recordings with the logs we collect, Jam's Recorder and Capture scripts need to be served under the *same origin* \[[MDN](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)] as your site or application.
{% endhint %}

Locate your **Team ID** in Jam.\
This is required to associate recordings and captured logs with your workspace.

You will add your Team ID to the `<meta name="jam:team" />` tag shown below.

<figure><img src="https://1990502200-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtAIPUIiSH7MWC0IHLJuD%2Fuploads%2FRxUD4EpP6M4GfRwv25wO%2Fimage.png?alt=media&#x26;token=ff943b89-9f7f-44ef-aabb-9f62abbd90a1" alt=""><figcaption></figcaption></figure>

#### Install the scripts

Paste the following snippet into the `<head>` tag of your site.

For best results, install it on all pages — or at minimum on the URL that will host your recording route.

We'll use Jam.js' Recorder and Capture scripts to initialize a recorder on your page and associate captured events.

```html
<html>
  <head>
    <!-- Lets users record their screen from your site -->
    <meta name="jam:team" content="my-team-id-from-dashboard" />
    <script type="module" src="https://js.jam.dev/recorder.js"></script>

    <!-- Captures user events and developer logs -->
    <script type="module" src="https://js.jam.dev/capture.js"></script>
  </head>
</html>
```

{% hint style="info" %}
Tip: In Jam's [recording links settings page](https://jam.dev/s/settings/recording-links) you can copy the script with your correct team ID already in.&#x20;
{% endhint %}

Make sure:

* The scripts load successfully
* They are not blocked by your Content Security Policy (CSP)
* They are available on the URL you plan to verify later

Do not proceed to domain verification until this step is complete.

#### What each script does

**recorder.js**

* Displays the recording interface when a recording link is opened
* Allows users to record their screen directly from your site

If a user dismisses the recorder before starting a recording, they must reopen the recording link to try again.

If a recording is in progress and the user attempts to close the recorder, Jam will ask them to confirm before discarding the recording.

Once a Jam is submitted, the recorder closes automatically and returns control to your page.

***

**capture.js**

* Captures console logs
* Captures network requests
* Captures clicks and key interactions

Events are collected only while a recording is in progress.\
Captured logs are automatically associated with the submitted Jam.

If no recording is active, events are ignored.

***

#### Performance

Jam assets are aggressively cached to minimize load impact.

The Capture script prioritizes critical code and defers non-essential logic to ensure your page continues to load and run smoothly.

{% hint style="warning" %}
Note: Jam.js' Capture script can only capture console and network requests made after it initializes.

The `<script>` tag should be placed as early as possible on the page, and should only use a lazy-loaded `import` when explicitly trading accuracy for un-cached load performance (e.g. on SEO-optimized pages).
{% endhint %}

### 2. Modify your Content-Security-Policy <a href="#id-3.-modify-your-content-security-policy" id="id-3.-modify-your-content-security-policy"></a>

*(If your site does not specify CSP directives, you can skip this step.)*

Some sites specify Content-Security-Policy \[[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)] directives via either a header or meta tag. A `frame-src` or `script-src` directive that doesn't include `*.jam.dev` will block Jam.js from including console logs with your user's Jams.

To fix this, modify your CSP header or meta tag to allow `*.jam.dev` as both. For example:

```
<meta
  http-equiv="Content-Security-Policy"
  content="frame-src 'self' *.jam.dev; script-src 'self' *.jam.dev;"
/>
```

### 3. Verify your domain <a href="#verify-logs-are-captured" id="verify-logs-are-captured"></a>

After installing the Recorder and Capture scripts, you must verify your domain before you can connect.

You cannot connect a domain unless verification succeeds.

To verify your domain

1. Go to: [**Settings → Recording Links**](https://jam.dev/s/settings/recording-links)
2. Click **Verify**.

<figure><img src="https://1990502200-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtAIPUIiSH7MWC0IHLJuD%2Fuploads%2F1x9vozqXxk8kVZAMUqGw%2FScreenshot%202026-03-02%20at%2010.49.30.png?alt=media&#x26;token=abd6604d-d0a3-4354-a0bc-23af326e4044" alt=""><figcaption></figcaption></figure>

Paste the URL where Jam scripts are installed.

Examples:

```
example.com
```

or

```
example.com/recorder
```

Click **Check setup**.

#### What verification checks

Jam verifies that:

* The page is publicly accessible
* The URL does not redirect
* Query parameters are preserved
* The Recorder script is installed
* The Capture script is installed

If any of these checks fail, verification will not complete.

#### Important: Redirects and query parameters

If your application redirects users from your recording URL (for example, redirecting unauthorized users to a login page), you must preserve Jam’s query parameters through the redirect.

The most important parameter is:

```
jam-recording=...
```

However, **all `jam-` parameters must be preserved**.

If your app strips or rewrites these parameters, the recorder will not initialize correctly and verification will fail.

{% hint style="info" %}
Before verifying, open your recording URL in an incognito window.\
If it redirects or removes query parameters, you need to adjust your routing.
{% endhint %}

***

#### Domain scope and log visibility

You must verify at least one URL per domain you want to capture logs from.

Recordings only have access to debug data from pages that:

* Run the Capture script
* Are on the same domain that initiated the recording

***

#### Root domain and subdomains

In most cases:

* A recorder installed on the root domain (e.g. `example.com`) can capture events from subdomains (e.g. `sub.example.com`)
* A recorder installed on a subdomain can capture events from the root domain

However:

{% hint style="warning" %}
**Safari limitation**

In Safari, logs are only captured when the recorder and capture script are running on the exact same subdomain.
{% endhint %}

Example:

* A recorder on `example.com/recorder` can capture events from `sub.example.com` — except in Safari.
* In Safari, both must run on the same subdomain.

If Safari support is critical for your team, consider installing the recorder on the same subdomain where users are active.

#### Confirm your domain is connected

If verification succeeds:

* Your domain is connected
* Recording links load from your domain
* Console logs and network requests will be captured

<figure><img src="https://1990502200-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtAIPUIiSH7MWC0IHLJuD%2Fuploads%2FN0tel0LygLgMYJ9btuld%2FScreenshot%202026-03-02%20at%2010.51.58.png?alt=media&#x26;token=d3eaeeb9-4e89-4758-9b4c-e605a1f1bd62" alt=""><figcaption></figcaption></figure>

***

#### If verification fails

Common causes:

* Team id miss match
* Scripts are not installed
* Scripts are blocked by CSP
* The URL requires authentication
* The URL redirects
* Query parameters are stripped
* Recorder and Capture scripts are on different domains

Fix the issue and retry verification.

## FAQs

<details>

<summary>Can I put the Recorder and Capture scripts on different pages?</summary>

Yes.

If you install them separately:

* The `<meta name="jam:team" />` tag **must** be present on pages where `recorder.js` is installed.
* It is optional on pages that only include `capture.js`.

Logs will only be captured from pages where the Capture script is running.

</details>

<details>

<summary>Can I programmatically create Recording Links directly on my page?</summary>

Not at this time.

We plan to expose an API that will allow you to create Recording Links programmatically (for example, from Slack, Zendesk, or directly within your app).

</details>

<details>

<summary>Can I customize the Recorder UI?</summary>

Not currently.

If you have specific customization requirements, contact us. We are actively evaluating improvements in this area.

</details>

<details>

<summary>Can I mix Jam recordings with custom recording infrastructure?</summary>

No.

Jam’s Recorder and Capture scripts are designed to work together. Due to browser storage and cross-origin restrictions, they must be used as a complete pair.

Partial integrations or mixing with external recording systems are not supported.

</details>

## Current limitations

<details>

<summary>Verification requirement</summary>

Logs will not be captured unless your domain has been successfully verified in:

**Settings → Recording Domain**

Installing the scripts alone is not sufficient.

</details>

<details>

<summary>Browser support</summary>

Log capture is fully supported in:

* Chrome (including Incognito)
* Firefox (including Private Windows)

Supported in most Safari windows.

Not supported in:

* Safari Private Windows

</details>

<details>

<summary>Domain and subdomain behavior</summary>

Recordings only capture logs from pages running the Capture script.

Logs are only accessible from pages on the same domain that initiated the recording.

In most cases, a recorder installed on a root domain (e.g. `example.com`) can capture events from subdomains (e.g. `sub.example.com`).

However:

In Safari, logs are only captured when the recorder and capture scripts run on the exact same subdomain.

</details>

<details>

<summary>Iframe limitation</summary>

If the Capture script is installed inside an iframe:

* Top-level logs will not be captured.

For example, embedded Shopify apps cannot capture logs from the parent page.

</details>

<details>

<summary>Script loading behavior</summary>

If you load the Capture script using:

* `async`
* `defer`
* Lazy-loaded `import(...)`

We cannot guarantee it will initialize early enough to capture:

* Early console logs
* Initial network requests
* Early page events

For full log coverage, load the scripts synchronously in the `<head>` section of your page.

</details>


---

# 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://jam.dev/docs/administration/set-up-a-custom-recording-domain.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.
