Skip to content

Cómo Agregar Traducciones a tu Aplicación Node.js con Azbox: Guía Completa

Aprende cómo integrar traducciones en tu aplicación Node.js usando el paquete azbox-node. Esta guía completa cubre integración de API, gestión de traducciones, caché, manejo de errores y mej

  • date icon

    20 de enero de 2025

  • 03 min de lectura
Cómo Agregar Traducciones a tu Aplicación Node.js con Azbox: Guía Completa

Azbox publica un cliente pequeño para Node.js, azbox-node. Esta guía cuenta qué hace realmente —menos de lo que parece— y cómo montar encima una capa de traducción que funcione.

Qué hace el cliente, y qué no

El paquete publicado expone exactamente una clase con un método:

export declare class AzboxClient {
  constructor(options: { token: string; projectId: string; language: string; baseUrl?: string });
  getKeywords(options?: { afterUpdatedAt?: Date }): Promise<AzboxKeyword[]>;
}

Eso es toda la superficie de la API. En concreto:

  • Solo lee. No hay ningún método para subir strings. Las keywords se crean en el panel de Azbox, una a una con Add Keyword o importando un archivo (ARB, JSON/i18next, .xcstrings, XML, XLSX, CSV, YAML o PHP). Ver la guía rápida de Azbox.
  • Trae un idioma cada vez. language se fija en el cliente, no por llamada. Para varios idiomas, un cliente por idioma.
  • No existe ningún translate(). Recibes la lista completa de keywords y haces la búsqueda tú. De eso va casi toda esta guía.

La credencial se pasa como token, no como apiKey. Pasar apiKey lanza AzboxClient: 'token' is required.

Requisitos

  • Node.js 18 o superior — el cliente usa el fetch global
  • Un proyecto de Azbox, con su Project ID y su API key
  • Algunas keywords ya creadas en el panel

Paso 1: instalar

npm install azbox-node

Paso 2: traer las keywords

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", context, reference, ... } }]

Por debajo es una sola llamada a GET https://api.azbox.io/v1/projects/:projectId/keywords?token=…&language=….

Paso 3: convertir la lista en un índice

getKeywords() devuelve un array. Llamarlo por cada string sería una petición HTTP por string, así que se trae una vez al arrancar y se construye un mapa:

// i18n.ts
import { AzboxClient } from "azbox-node";

type Dictionary = Map<string, string>;
const dictionaries = new Map<string, Dictionary>();

export async function loadLanguage(language: string): Promise<Dictionary> {
  const client = new AzboxClient({
    token: process.env.AZBOX_API_KEY!,
    projectId: process.env.AZBOX_PROJECT_ID!,
    language,
  });

  const keywords = await client.getKeywords();
  const dict: Dictionary = new Map(
    keywords
      .filter((kw) => typeof kw.data.translation === "string")
      .map((kw) => [kw.id, kw.data.translation as string]),
  );

  dictionaries.set(language, dict);
  return dict;
}

export function t(language: string, key: string, params?: Record<string, string | number>) {
  const value = dictionaries.get(language)?.get(key);
  if (value === undefined) return key; // devolver la clave, nunca una cadena vacía
  if (!params) return value;
  return value.replace(/\{(\w+)\}/g, (m, p) => String(params[p] ?? m));
}

La interpolación corre de tu cuenta: la API devuelve la cadena tal como está guardada, con sus placeholders.

Paso 4: cargar al arrancar, no por petición

const LANGUAGES = ["EN", "ES", "FR"];

await Promise.all(LANGUAGES.map(loadLanguage));

app.listen(3000);

Si un idioma falla al cargar, decide a conciencia si arrancar igualmente con un fallback o fallar de forma ruidosa. Arrancar con un diccionario a medias y sin log es como se acaba enseñando claves crudas a los usuarios.

Paso 5: refrescar solo lo que cambió

getKeywords() acepta afterUpdatedAt, que se traduce al parámetro afterUpdatedAtStr. Sirve para consultar cambios sin volver a traerlo todo:

const lastSync = new Map<string, Date>();

export async function refresh(language: string) {
  const since = lastSync.get(language);
  const client = new AzboxClient({
    token: process.env.AZBOX_API_KEY!,
    projectId: process.env.AZBOX_PROJECT_ID!,
    language,
  });

  const changed = await client.getKeywords(since ? { afterUpdatedAt: since } : {});
  const dict = dictionaries.get(language) ?? new Map();

  for (const kw of changed) {
    if (typeof kw.data.translation === "string") dict.set(kw.id, kw.data.translation);
  }

  dictionaries.set(language, dict);
  lastSync.set(language, new Date());
  return changed.length;
}

Esto es lo que hace posibles las actualizaciones over-the-air en el servidor: corriges un texto en el panel y el siguiente refresco lo recoge sin desplegar.

Paso 6: middleware de Express

import express from "express";
import { t } from "./i18n";

const app = express();

app.use((req, res, next) => {
  const header = req.headers["accept-language"] ?? "";
  const lang = String(header).slice(0, 2).toUpperCase();
  req.language = ["EN", "ES", "FR"].includes(lang) ? lang : "EN";
  next();
});

app.get("/api/welcome", (req, res) => {
  res.json({ message: t(req.language, "home.title", { name: "Ada" }) });
});

Manejo de errores

getKeywords() lanza si la respuesta no es 2xx y si el payload no es el esperado. Un refresco fallido no es fatal: ya tienes el diccionario anterior en memoria.

setInterval(() => {
  refresh("ES").catch((err) => console.error("[i18n] refresco fallido:", err.message));
}, 5 * 60 * 1000);

De dónde salen los strings

Conviene repetirlo, porque es la parte que todo el mundo espera automatizar y no se puede: las keywords se crean en el panel, no desde el código. El flujo habitual es importar una vez tu en.json existente (o ARB, o XML), traducir en Azbox y dejar que la aplicación se traiga el resultado con el cliente de arriba.

Si necesitas crearlas programáticamente, el cliente no lo hace: tendrías que llamar directamente a la API HTTP de Azbox.

Blog

Últimas Publicaciones

Descubre nuestros últimos artículos y actualizaciones.

Servicios de localización de videojuegos: guía 2026 para llevar tu juego al mundo
date icon

21 de febrero de 2026

05 min de lectura

Servicios de localización de videojuegos: guía 2026 para llevar tu juego al mundo

Llevar tu juego a nivel global no es solo traducir texto: es hacer que los jugadores de cada mercado sientan que el jueg

Leer más
Software de localización de apps: guía 2026 para elegir y usar la herramienta adecuada
date icon

20 de febrero de 2026

05 min de lectura

Software de localización de apps: guía 2026 para elegir y usar la herramienta adecuada

Si estás llevando tu app más allá de un solo idioma, el software de localización de apps es la palanca que convierte

Leer más
Traducción para SaaS: Guía Completa para Localizar Tu Producto
date icon

15 de febrero de 2026

04 min de lectura

Traducción para SaaS: Guía Completa para Localizar Tu Producto

La traducción para SaaS ya no es opcional. Si quieres crecer más allá de tu mercado local, necesitas una estrategia

Leer más
Fondo de llamada a la acción

Comienza el Crecimiento Global Hoy

Sube tus archivos de idioma, recibe las traducciones y mantén cada idioma sincronizado mientras tu producto sigue cambiando.

Comenzar - Es Gratis