Quickstart · Node.js
Updated: September 7, 2026
Target: a Node service serving translated strings, in under ten minutes. Read the first section before writing code — the client does less than its name suggests, and knowing that up front saves an hour.
What the client does
azbox-node exposes exactly one class with one method:
new AzboxClient({ token, projectId, language })
await client.getKeywords({ afterUpdatedAt? })
Three consequences:
- It only reads. Keywords are created in the panel; there is no upload method.
- One language per client. For several languages, one client each.
- No
translate()helper. You get the list and build the lookup yourself. That is steps 4 and 5 below.
The credential is token, not apiKey. Passing apiKey throws AzboxClient: 'token' is required.
Before you start
- Node 18 or newer — the client uses the global
fetch - An AZbox project with its Project ID and API key
1 · Create the project and import your strings
In the dashboard: Create Project, then import your en.json (i18next format is read natively, nested keys included) or add keywords with Add Keyword.
2 · Install
npm install azbox-node
3 · Fetch
import { AzboxClient } from "azbox-node";
const client = new AzboxClient({
token: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID,
language: "ES",
});
const keywords = await client.getKeywords();
// [{ id: "home.title", data: { translation: "Bienvenido", ... } }]
One call to GET /v1/projects/:id/keywords?token=…&language=….
4 · Build the lookup
Calling getKeywords() per string would be one HTTP request per string. Fetch once at startup:
const dictionaries = new Map<string, Map<string, string>>();
export async function loadLanguage(language: string) {
const client = new AzboxClient({
token: process.env.AZBOX_API_KEY!,
projectId: process.env.AZBOX_PROJECT_ID!,
language,
});
const keywords = await client.getKeywords();
dictionaries.set(language, new Map(
keywords
.filter((k) => typeof k.data.translation === "string")
.map((k) => [k.id, k.data.translation as string]),
));
}
export function t(language: string, key: string, params?: Record<string, string | number>) {
const value = dictionaries.get(language)?.get(key);
if (value === undefined) return key;
return params
? value.replace(/\{(\w+)\}/g, (m, p) => String(params[p] ?? m))
: value;
}
Interpolation is yours: the API returns the string as stored, placeholders included.
5 · Refresh only what changed
const changed = await client.getKeywords({ afterUpdatedAt: lastSync });
This is what makes over-the-air work on the server: correct a string in the panel and the next refresh picks it up without a deploy. A failed refresh is not fatal — you still hold the previous dictionary in memory.
6 · In CI
env:
AZBOX_API_KEY: ${{ secrets.AZBOX_API_KEY }}
AZBOX_PROJECT_ID: ${{ secrets.AZBOX_PROJECT_ID }}
If something fails
'token' is required— you passedapiKey. The option istoken.- Empty array — the project has no keywords in that language, or the language code does not match the one configured in the project.
fetch is not defined— Node older than 18.
Next
Start Global Growth Today
Upload your language files, get them translated, and keep every locale in sync as your product keeps changing.
Get Started - It's Free