# Widget reference

> Every option, as a config key and as a data attribute, plus the window.Jot API.

Source: https://docs.usejot.co/docs/widget

## Options

Every option exists twice: as a `data-jot-*` attribute on the
[script tag](/docs/install/script), and as a config key in the
[packages](/docs/install/react). They mean exactly the same thing.

| Config key    | Attribute            | Default   | What it does                                                            |
| ------------- | -------------------- | --------- | ----------------------------------------------------------------------- |
| `projectKey`  | `data-jot-key`       | —         | **Required.** Your project key, from **Project → Settings**             |
| `trigger`     | `data-jot-trigger`   | `"fab"`   | `"fab"` is the round Jot button; `"tab"` is a vertical **FEEDBACK** tab |
| `edge`        | `data-jot-edge`      | `"right"` | Which side the trigger sits on: `"left"` or `"right"`                   |
| `offset`      | `data-jot-offset`    | `50`      | Vertical position, as a percent of the viewport height                  |
| `environment` | `data-jot-env`       | —         | Tags every report with an environment. Trimmed and lowercased           |
| `autostart`   | `data-jot-autostart` | `true`    | `false` keeps the widget unmounted until you call `Jot.init()`          |
| —             | `data-jot-internal`  | —         | `"true"` hides the widget from ordinary visitors — see below            |

```html
<script
  src="https://cdn.jsdelivr.net/npm/@usejot/widget@1/dist/jot.js"
  data-jot-key="jot_pk_your_key"
  data-jot-trigger="tab"
  data-jot-edge="left"
  data-jot-env="staging"
></script>
```

## Environments

`environment` stamps every Jot from that page with a name you choose —
`staging`, `preview-142`, `production`. Filter the inbox by it so production
reports and preview noise never mix. Agents can filter by it too.

## Internal only

`data-jot-internal="true"` keeps the widget invisible to your customers on a
public page:

1. The widget mounts only when the page is opened with `?jot=true` in the URL.
2. The browser remembers that, so later visits stay in. `?jot=false` forgets it.

Pair it with **Internal-only mode** in **Project → Settings → Who can leave Jots**
so Jot also refuses anyone who isn't a signed-in team member.

Calling `Jot.init()` yourself skips the `?jot=true` check — your page's own code
deciding to show the widget is consent enough.

## `window.Jot`

The script defines one global.

| Call            | Does                                                                      |
| --------------- | ------------------------------------------------------------------------- |
| `Jot.init()`    | Mounts the widget. Use with `autostart: false`, e.g. after cookie consent |
| `Jot.open()`    | Opens the widget, as if the trigger was clicked                           |
| `Jot.destroy()` | Removes the widget from the page. `Jot.init()` brings it back             |
| `Jot.version`   | The API version, currently `"1"`                                          |

```js
// after your consent tool says yes:
window.Jot?.init();
```

Mounting twice is harmless — the second call does nothing. The packages call
`Jot.destroy()` for you when their component unmounts.

## What it does to your page

As little as possible:

* Renders inside a **shadow root** — no styles cross in either direction.
* Sits out of the page flow — **zero layout shift**, no new scrollbar.
* Never changes your `<body>` styles and never traps focus while closed.
* Loads in stages: a loader of about a kilobyte up front, the rest when someone
  opens it, the recorder only when someone presses **Record**.

## Privacy classes

| Class        | Effect                                                 |
| ------------ | ------------------------------------------------------ |
| `jot-mask`   | Text masked in recordings, painted over in screenshots |
| `jot-block`  | Left out of recordings, painted over in screenshots    |
| `jot-ignore` | Typing in it is not recorded                           |

More in [Privacy & masking](/docs/privacy).
