> ## Documentation Index
> Fetch the complete documentation index at: https://docs.focale.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Install watching

> Merge the focale pull request, or add the SDK and FOCALE_DSN yourself.

Most of the time you should [finish onboarding](/quickstart) and let focale open the watching pull request. Merge it if it is still open, set your ingest DSN as a host secret, then publish.

The PR adds a boot file (`focale.instrument.mjs`) and wraps the handlers you confirmed with [`watch()`](/watch). The example env file uses a placeholder, not the live key.

<Warning>
  Never commit the live ingest key. Put `FOCALE_DSN` in `.env` locally, or in your host's secret store (Lovable, Bolt, Vercel, Railway, and the like). The key is not a GitHub token.
</Warning>

## DSN

```bash theme={null}
FOCALE_DSN=https://<key>@intake.focale.io
```

focale gives you this value. Copy it into secrets. See [DSN](/dsn) for the shape.

## Manual install

Use this if the PR did not land, or you want to add watching yourself.

<Tabs>
  <Tab title="Node">
    Node is the runtime focale lands today.

    ```bash theme={null}
    npm install @focale/sdk @focale/sdk-node
    ```

    Call `start()` once when the process boots, then wrap the handler you care about:

    ```javascript theme={null}
    import { start } from '@focale/sdk-node';
    import { watch } from '@focale/sdk';

    await start(); // reads FOCALE_DSN

    export const POST = watch('auth.signup', async (req) => {
      // existing handler
    });
    ```

    The file focale would have added looks like this:

    ```javascript theme={null}
    import { start } from '@focale/sdk-node';
    await start();
    ```
  </Tab>

  <Tab title="Browser">
    Browser `start()` exists so a page can share the same DSN. Automatic browser watching is not in scope yet.

    ```bash theme={null}
    npm install @focale/sdk @focale/sdk-browser
    ```

    ```javascript theme={null}
    import { start } from '@focale/sdk-browser';
    import { watch } from '@focale/sdk';

    start(); // reads FOCALE_DSN
    ```
  </Tab>

  <Tab title="Deno">
    Deno `start()` is a stub around the same core.

    ```typescript theme={null}
    import { start } from '@focale/sdk-deno';
    import { watch } from '@focale/sdk';

    start();
    ```
  </Tab>

  <Tab title="Edge">
    Edge `start()` is a stub around the same core.

    ```javascript theme={null}
    import { start } from '@focale/sdk-edge';
    import { watch } from '@focale/sdk';

    start();
    ```
  </Tab>
</Tabs>

<Tip>
  If you already send OpenTelemetry yourself, you can skip the SDK. See [OTLP](/otlp).
</Tip>
