---
url: /custom-pages/client-side-serverclient.md
description: >-
  A lightweight fetch wrapper for making requests to the /serverside/execute
  endpoint, with optional request deduplication, abort control, and structured
  error handling.
---

# ServerClient&#x20;

A lightweight fetch wrapper for making requests to the `/serverside/execute` endpoint, with optional request deduplication, abort control, and structured error handling.

## Server-side page requirement

The target server-side page must support a second parameter in the page function.

```js
function request(data, method) {
    return { data, method };
}
```

## Constructor

```js
new ServerClient(defaultHeaders?)
```

## Methods

| Method | Signature | Description |
| --- | --- | --- |
| `get` | `(page, params?, options?)` | GET request with optional query params |
| `post` | `(page, data?, options?)` | POST request with a JSON body |
| `put` | `(page, data?, options?)` | PUT request with a JSON body |
| `patch` | `(page, data?, options?)` | PATCH request with a JSON body |
| `delete` | `(page, params?, options?)` | DELETE request with optional query params |
| `abort` | `(page, method?, params?)` | Cancel a specific in-flight request |
| `abortAll` | `()` | Cancel all in-flight requests |

## Key behaviours

* Optional deduplication - deduplication is off by default and can be enabled per request with `dedupe: true`. When enabled, if the same `method + URL` is already in flight, the previous request is aborted automatically.
* Signal passthrough - accepts an external `AbortSignal` through `options.signal`, merged with the internal controller.
* Error handling - non-2xx responses throw `ServerClient.Error` with `status`, `statusText`, and `body`; abort errors throw with status `0`.
* `204` handling - returns `null` instead of attempting to parse an empty response body.
* JSON requests - request bodies are serialized as JSON and `Content-Type: application/json` is set automatically.

## Error handling

Non-2xx responses and aborted requests throw `ServerClient.Error`, a typed subclass of `Error`.

| Property | Type | Description |
| --- | --- | --- |
| `status` | `number` | HTTP status code, or `0` for aborted requests |
| `statusText` | `string` | HTTP status text, or `Request aborted` |
| `body` | `string` | Response body text, if any |

```js
try {
    const data = await http.post('my-page.js', payload);
} catch (err) {
    if (err instanceof ServerClient.Error) {
        console.log(err.status, err.body);
    }
}
```

## Examples

```js
const http = new ServerClient();

// GET with query params
const user = await http.get('user.js', { id: 42 });

// POST with a JSON body
const result = await http.post('save.js', { name: 'Alice' });

// Opt-in dedupe, useful for repeated searches
const results = await http.post('search.js', { query }, { dedupe: true });

// Cancellable request
const controller = new AbortController();
http.get('slow.js', {}, { signal: controller.signal });
controller.abort();

// Cancel all in-flight requests
http.abortAll();
```

```js
// Normal request: no dedupe
http.post('save.js', data);

// Opt-in dedupe
http.post('search.js', { query }, { dedupe: true });
```
