DocsJavaScript — browser and Node7 min read

JavaScript — browser and Node

siyak-js is one file, no dependencies, and the same object in the browser and on the server. ESM and CommonJS, Node 18 and up, any bundler.

npm install ./siyak-js-0.1.0.tgz    # the file you just downloaded
import { init } from 'siyak-js';        // ESM
const { init } = require('siyak-js');    // CommonJS

Options

apiKeystring
Required. sk_live_<40 hex> or sk_test_<40 hex>. Malformed values are caught locally, before a single request is spent.
targetstring
Required. BCP-47 tag: "ar", "ar-EG", "he", "ur". A bad tag fails every call, so it is validated at init.
sourcestring
Optional. Omit it and the project's configured source language is used.
contextstring
Optional default meaning, overridable per call. Prefer per-call context — a global one makes every string the same screen.
endpointstring
Required. Bare host; /v1 is appended. Copy the address printed on your project’s API keys screen. The SDK carries no default host on purpose: a fallback domain is one anybody could register later, and a key that reaches it is a leaked key. Set it to a local server or your own deployment instead.
cachefalse | {maxEntries, ttlMs}
false keeps translations in memory only — what you want under SSR, in tests, and on any page you do not own. Default 1000 entries, 30 days.
debounceMsnumber
Coalescing window for background misses. Default 50. Lower it if you flush() by hand anyway.
onError(e) => void
Every failure the SDK otherwise swallows arrives here: {code, message, status}.
fetchSiyakFetch
Inject a custom fetch — tests, or a runtime without a global one.

Methods

t(text, context?)string
Sync, never throws. Cached translation, or your string with a fetch queued behind it.
translate(text, context?)Promise<string>
Awaits the network. Resolves with the source text on any failure — it never rejects.
preload()Promise<void>
One GET /v1/strings fills the cache with everything the project already knows.
flush()Promise<void>
Sends the queue now and resolves when nothing is in flight. Use it in Node, in tests, and before a snapshot.
onReadyPromise<void>
Resolves once the queue and the network are idle. Re-read it after more calls; it is fresh every time.
clearCache()void
Drops this instance's cached strings from memory and storage.

Browser

main.js
const siyak = init({
  apiKey: import.meta.env.VITE_SIYAK_KEY,
  endpoint: import.meta.env.VITE_SIYAK_URL,
  target: 'ar',
});

// Paint instantly, then repaint once the batch lands.
const render = () => document.getElementById('app')!.replaceChildren(t('Continue'));
siyak.t('Continue');
await siyak.onReady;
render();

Node.js and CLIs

server.js
const siyak = init({
  apiKey: process.env.SIYAK_KEY,
  endpoint: process.env.SIYAK_URL,
  target: 'ar',
  cache: false,           // no localStorage on a server
});

// A server render cannot repaint, so await the work it queues.
siyak.t('Your order has shipped');
siyak.t('Track shipment', 'screen:checkout');
await siyak.flush();

res.send(page({ continue: siyak.t('Continue') }));   // warm now
  • Node 18+ has a global fetch; older runtimes must pass one via the fetch option.
  • The allowed-domain list guards browser keys. A server key has no browser to guard, so keep it in the environment, not in the bundle.
  • A server has no user to repaint, so flush() before you render — t() alone would ship source text.

Batching, in one paragraph

Every miss inside debounceMs is sent as one POST /v1/translate/batch, in chunks of 20. Two calls to t() with the same text and context are one request. A 402 or a 429 parks the instance for the rest of the session: an app must never DDoS the API over a billing problem, so strings simply stay in the source language.