Skip to content
cable
Esc
↑↓navigate↵open⌘Jpreview
On this page

Use the client

Call cable procedures and manage typed channels with batched HTTP, reconnecting sockets, presence, durable replay, and explicit resource ownership.

@cablejs/client imports the shared contract and calls procedures through HTTP batches. It does not import server implementations.

import { createClient } from "@cablejs/client";
import { api } from "./contract.js";

const client = createClient({
  contract: api,
  url: "https://api.example.com/_cable",
  auth: { token: () => sessionStorage.getItem("token") ?? undefined },
});

const posts = await client.posts.list.query({});
await client.posts.create.mutate({ title: "A new post" });

Concurrent procedure calls share a POST batch. The default batch has a limit of 20 requests or 10 milliseconds. batchLink({ maxBatch, maxWait }) changes those limits.

Cancel an HTTP procedure

Pass an AbortSignal as the second argument when a view no longer needs a query or mutation:

const controller = new AbortController();
const pending = client.posts.list.query({ limit: 20 }, { signal: controller.signal });

controller.abort();
await pending.catch(() => undefined);

An aborted call is removed from a queued batch, and a different signal starts a separate batch. The server receives the request signal when its runtime supports it; handlers must observe signal.aborted or the signal’s abort event for cooperative cancellation. Cancellation does not roll back a mutation, retry it, or add cancellation frames to channel sockets.

Enable channels

Pass the runtime contract when the client uses channels. A channel handle opens its socket when the application subscribes, sends an event, or updates presence.

import { api } from "./contract.js";

const client = createClient({ contract: api, url: "/_cable" });
const room = client.chat({ roomId: "general" });
const off = room.on("message", (message) => console.log(message));

await room.send({ text: "Hello" }, { ack: true });
room.presence.update({ typing: true });

off();
room.dispose();

Handles for the same canonical channel key share one connection within a client. Dispose each handle when the application no longer needs it. The final release closes the socket after 30 seconds by default; configure the delay with ws.idleClose.

Reconnect and history

Reconnect uses exponential backoff. cable resumes from the last delivered event and waits for the final welcome chunk before reporting open. A retained-history gap emits reset. Optional ws.cursors persists sequence cursors through a sessionStorage-compatible store.

Acknowledged channel events and host calls reject when their connection is interrupted. cable does not repeat them automatically. See channels for presence, history, and lifecycle ownership, and reliability for the recovery boundary.

Next, connect the client to Cloudflare.

Was this page helpful?