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, qué no hace y cómo montar encima una capa de traducción que funcione.

Actualizado en septiembre de 2026. Las versiones 0.1.0 y 0.1.1 de azbox-node no funcionaban contra la API. Usa la 0.2.0 o superior; los ejemplos de abajo están escritos para ella.

Qué hace el cliente, y qué no

El paquete es una clase:

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

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 ninguna función t(). Recibes un diccionario y haces la búsqueda tú. De eso va casi toda esta guía.

Requisitos

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

Paso 1: instalar

npm install azbox-node

Paso 2: traer las traducciones

import { AzboxClient } from "azbox-node";

const client = new AzboxClient({
  apiKey: process.env.AZBOX_API_KEY,
  projectId: process.env.AZBOX_PROJECT_ID,
  language: "ES",
});

const translations = await client.getTranslations();
// { "home.title": "Bienvenido", … }

Por debajo es una sola llamada a GET https://api.azbox.io/v1/projects/:projectId/keywords. Las keywords que aún no tienen texto en ese idioma se quedan fuera. getKeywords() devuelve en cambio la respuesta tal cual, [{ id, data: { keyword, translation, … } }], donde la clave es data.keyword y el id es un identificador interno.

Paso 3: un diccionario por idioma

Llamar a la API por cada string sería una petición HTTP por string, así que se trae una vez al arrancar:

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

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

function clientFor(language: string) {
  return new AzboxClient({
    apiKey: process.env.AZBOX_API_KEY!,
    projectId: process.env.AZBOX_PROJECT_ID!,
    language,
  });
}

export async function loadLanguage(language: string): Promise<Dictionary> {
  const dict = await clientFor(language).getTranslations();
  dictionaries.set(language, dict);
  return dict;
}

export function t(language: string, key: string, params?: Record<string, string | number>) {
  const value = dictionaries.get(language)?.[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ó

Los dos métodos aceptan 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 startedAt = new Date();

  const changed = await clientFor(language).getTranslations(since ? { afterUpdatedAt: since } : {});
  dictionaries.set(language, { ...dictionaries.get(language), ...changed });

  lastSync.set(language, startedAt);
  return Object.keys(changed).length;
}

La hora de sincronización se toma antes de la petición: así, un texto editado mientras la petición está en vuelo se recoge en el siguiente refresco en vez de perderse.

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

El cliente lanza AzboxError, con status (401 si la clave es incorrecta o está revocada, 403 si no tiene acceso al proyecto) y el detail de la API. Un proyecto sin keywords todavía no es un error: recibes un resultado vacío. Un refresco fallido no es fatal: ya tienes el diccionario anterior en memoria.

setInterval(() => {
  refresh("ES").catch((err) => console.error("[i18n] refresco fallido:", err.status, 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. La API es de solo lectura para keywords, así que no hay forma de crearlas por programa.

Si lo que necesitas son ficheros de traducción en disco y no un diccionario en memoria, el CLI de AZbox los escribe sin código.

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