> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/clyrisai/gitresolve/llms.txt
> Use this file to discover all available pages before exploring further.

# Browserless Provider — Remote Headless Chrome | GitResolve

> BrowserlessProvider delegates JavaScript rendering to a Browserless Docker container over REST, with no local Chromium binary required.

`BrowserlessProvider` offloads page rendering to a running [Browserless](https://www.browserless.io) instance over its REST API. Instead of managing a local Chromium process, GitResolve sends a `POST /content` request to the Browserless server and receives back the fully rendered HTML. The provider itself is entirely stateless — there is no browser lifecycle to manage, no process to terminate, and `cleanup()` is a no-op.

## When to use

* **Production servers** where installing a full browser binary is undesirable or against policy
* **CI/CD pipelines** that run Browserless as a sidecar container alongside your test runner
* **Restricted environments** such as read-only filesystems or minimal base images that cannot host a Chromium install
* **Shared rendering infrastructure** where a single Browserless instance serves multiple GitResolve workers

## Docker setup

Start a Browserless container before running GitResolve:

```bash theme={null}
docker run -d \
  --name browserless \
  -p 3000:3000 \
  ghcr.io/browserless/chromium
```

The container exposes its REST API on port 3000 by default. GitResolve will connect to `http://localhost:3000` unless you specify a different address.

## Configuration

`BrowserlessProvider` resolves its base URL from three sources, checked in this order:

| Source                                 | Example                                              |
| -------------------------------------- | ---------------------------------------------------- |
| Constructor argument                   | `new BrowserlessProvider('http://browserless:3000')` |
| `BROWSERLESS_URL` environment variable | `export BROWSERLESS_URL=http://browserless:3000`     |
| Default                                | `http://localhost:3000`                              |

## Usage

### Direct instantiation

```typescript theme={null}
import { BrowserlessProvider } from '@clyrisai/gitresolve';

// Uses BROWSERLESS_URL env var or falls back to http://localhost:3000
const provider = new BrowserlessProvider();

const html = await provider.getPageContent('https://github.com/torvalds');
console.log(html.slice(0, 500));

// cleanup() is a no-op — safe to call, but nothing happens
await provider.cleanup();
```

Pass an explicit URL to target a non-default instance:

```typescript theme={null}
const provider = new BrowserlessProvider('http://browserless.internal:3000');
const html = await provider.getPageContent('https://gitlab.com/someone');
```

### Via the factory

```typescript theme={null}
import { createProvider } from '@clyrisai/gitresolve';

// BROWSERLESS_URL must be set, or browserless must be reachable at localhost:3000
const provider = await createProvider('browserless');
const html = await provider.getPageContent('https://bitbucket.org/someone');
```

### CLI

To use `BrowserlessProvider` from the command line, set the `BROWSER_PROVIDER` and `BROWSERLESS_URL` environment variables:

```bash theme={null}
BROWSERLESS_URL=http://browserless:3000 BROWSER_PROVIDER=browserless gitresolve resolve resume.pdf
```

## How it works

<Steps>
  <Step title="POST to /content">
    `getPageContent` sends a `POST` request to `{baseUrl}/content` with a JSON body containing the target `url` and `gotoOptions` (`waitUntil` and `timeout`). Browserless navigates to the URL inside a managed Chromium instance and returns the fully rendered HTML.
  </Step>

  <Step title="Response handling">
    If the Browserless server returns a 2xx status, GitResolve reads the response body as text and returns it. A non-2xx response throws `Error: Browserless /content returned <status>: <statusText> <body>`.
  </Step>

  <Step title="Availability check">
    `isAvailable()` performs a `GET {baseUrl}/json/version` with a 3-second timeout. If the server responds with a 2xx status, the provider is considered available. Any network error or non-2xx response returns `false`.
  </Step>

  <Step title="Cleanup (no-op)">
    Because Browserless is a stateless REST service — it manages its own browser pool internally — `cleanup()` does nothing. There are no local resources to release.
  </Step>
</Steps>

## Options

| Option      | Type     | Default          | Description                                                                                                                                        |
| ----------- | -------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `timeout`   | `number` | `30000`          | Maximum milliseconds Browserless waits for the page to reach the `waitUntil` state. Passed as `gotoOptions.timeout`.                               |
| `waitUntil` | `string` | `'networkidle2'` | Navigation completion condition. Passed as `gotoOptions.waitUntil`. Accepts `'load'`, `'domcontentloaded'`, `'networkidle0'`, or `'networkidle2'`. |

```typescript theme={null}
const html = await provider.getPageContent('https://example.com/spa', {
  waitUntil: 'networkidle0',
  timeout: 45000,
});
```

<Note>
  `cleanup()` is a no-op for `BrowserlessProvider`. Calling it is safe and idiomatic, but it performs no work — the Browserless container manages its own Chromium lifecycle independently.
</Note>
