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'); // CommonJSOptions
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.