Adding translations to your Node.js application is essential for reaching a global audience. Azbox provides a powerful translation API that can be easily integrated into your Node.js backend applications using the azbox-node package. This guide will walk you through the process of integrating translations into your Node.js application using Azbox.
Understanding Node.js Translation Integration with Azbox
Azbox is a cloud-based translation management platform that allows you to manage translations centrally and access them via API. The azbox-node package provides a simple interface to integrate Azbox translations into your Node.js backend applications, whether you’re building REST APIs, web servers, or backend services.
Prerequisites
Before you begin, make sure you have:
- Node.js 14+ installed on your system
- npm or yarn as package manager
- An Azbox account with a Starter plan or higher
- A configured Azbox Project
- Your API Key and Project ID from your Azbox project
Step 1: Install the Azbox Node.js Package
Install the azbox-node package from npm:
npm install azbox-node
Or if you prefer using yarn:
yarn add azbox-node
Step 2: Get Your Azbox Credentials
To use Azbox in your Node.js application, you’ll need:
- API Key: Found in your Azbox project settings
- Project ID: Also found in your project settings
You can find these credentials in your Azbox dashboard under your project settings.
Step 3: Configure Azbox in Your Node.js Application
Create a configuration file or initialize Azbox directly in your code. We recommend using environment variables for security.
Using CommonJS (require)
config/azbox.js:
const Azbox = require('azbox-node');
// Initialize Azbox with your credentials
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID
});
module.exports = azbox;
Or initialize directly:
const Azbox = require('azbox-node');
const azbox = new Azbox({
apiKey: 'Your API Key',
projectId: 'Your Project ID'
});
Using ES6 Modules (import)
config/azbox.js:
import Azbox from 'azbox-node';
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID
});
export default azbox;
Or initialize directly:
import Azbox from 'azbox-node';
const azbox = new Azbox({
apiKey: 'Your API Key',
projectId: 'Your Project ID'
});
Step 4: Set Up Environment Variables
Create a .env file in your project root to store your credentials securely:
.env:
AZBOX_API_KEY=your_api_key_here
AZBOX_PROJECT_ID=your_project_id_here
If you’re using dotenv, make sure to load it at the start of your application:
require('dotenv').config();
const Azbox = require('azbox-node');
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID
});
Step 5: Basic Translation Usage
Once configured, you can start using translation functions in your application.
Get a Single Translation
const Azbox = require('azbox-node');
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID
});
// Get a translation for a specific keyword
async function getTranslation() {
const translation = await azbox.translate('welcome_message', 'es');
console.log(translation); // Shows the translation in Spanish
}
getTranslation();
Get Translation with Default Language
If you don’t specify a language, Azbox will return the translation in your project’s default language:
async function getDefaultTranslation() {
const title = await azbox.translate('app_title');
console.log(title);
}
getDefaultTranslation();
Step 6: Get Multiple Translations
You can retrieve multiple translations at once for better performance.
Get All Translations for a Language
async function getAllTranslations() {
// Get all translations for Spanish
const translations = await azbox.getTranslations('es');
console.log(translations);
// Returns an object with all translations: { "keyword1": "translation1", ... }
}
getAllTranslations();
Get Multiple Specific Keywords
async function getMultipleTranslations() {
const keywords = ['title', 'subtitle', 'description', 'button_submit'];
const results = await azbox.getMultipleTranslations(keywords, 'es');
console.log(results);
// Returns: { "title": "...", "subtitle": "...", ... }
}
getMultipleTranslations();
Step 7: Translations with Parameters
Azbox supports translations with dynamic parameters, both positional and named arguments.
Translations with Positional Arguments
async function translationWithArgs() {
// Translation with positional arguments
const message = await azbox.translate('welcome_message', 'es', {
args: ['User', 'Azbox']
});
console.log(message); // "Welcome User to Azbox"
}
translationWithArgs();
Translations with Named Arguments
async function translationWithNamedArgs() {
// Translation with named arguments
const greeting = await azbox.translate('greeting', 'es', {
namedArgs: {
name: 'John',
time: 'morning'
}
});
console.log(greeting);
}
translationWithNamedArgs();
Step 8: Complete Express.js Example
Here’s a complete example of how to use Azbox in an Express.js application:
app.js:
const express = require('express');
const Azbox = require('azbox-node');
require('dotenv').config();
const app = express();
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID
});
// Middleware to add translations to request context
app.use(async (req, res, next) => {
// Get language from Accept-Language header or default to 'en'
const lang = req.headers['accept-language']?.split(',')[0]?.split('-')[0] || 'en';
try {
// Load all translations for the detected language
req.translations = await azbox.getTranslations(lang);
req.lang = lang;
} catch (error) {
// Fallback to default language if error
req.translations = await azbox.getTranslations('en');
req.lang = 'en';
}
next();
});
// Helper function to get translation
function t(req, key, params = {}) {
const translation = req.translations[key] || key;
// Simple parameter replacement
if (params && Object.keys(params).length > 0) {
return translation.replace(/\{\{(\w+)\}\}/g, (match, key) => {
return params[key] || match;
});
}
return translation;
}
// Example route using translations
app.get('/api/translate/:keyword', async (req, res) => {
try {
const { keyword } = req.params;
const lang = req.query.lang || req.lang;
const translation = await azbox.translate(keyword, lang);
res.json({ keyword, lang, translation });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Example route with translated response
app.get('/api/welcome', async (req, res) => {
const name = req.query.name || 'Guest';
const welcomeMessage = t(req, 'welcome_message', { name });
res.json({
message: welcomeMessage,
lang: req.lang
});
});
// Example route serving HTML with translations
app.get('/', async (req, res) => {
const html = `
<!DOCTYPE html>
<html lang="${req.lang}">
<head>
<title>${t(req, 'app_title')}</title>
</head>
<body>
<h1>${t(req, 'welcome_message', { name: 'User' })}</h1>
<button>${t(req, 'button_submit')}</button>
<button>${t(req, 'button_cancel')}</button>
</body>
</html>
`;
res.send(html);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Step 9: Error Handling
It’s important to handle errors properly when working with translations:
async function getTranslationSafely(keyword, lang = 'en') {
try {
const translation = await azbox.translate(keyword, lang);
return translation;
} catch (error) {
if (error.code === 'KEYWORD_NOT_FOUND') {
console.error(`The keyword "${keyword}" does not exist in the project`);
// Return the keyword as fallback
return keyword;
} else if (error.code === 'LANGUAGE_NOT_FOUND') {
console.error(`The language "${lang}" is not available`);
// Try to get translation in default language
try {
return await azbox.translate(keyword);
} catch (fallbackError) {
return keyword;
}
} else if (error.code === 'API_ERROR') {
console.error('Error connecting to Azbox API:', error.message);
// Return keyword as fallback
return keyword;
} else {
console.error('Unexpected error:', error.message);
return keyword;
}
}
}
// Usage
async function example() {
const translation = await getTranslationSafely('welcome', 'es');
console.log(translation);
}
Step 10: Implement Caching for Performance
To improve performance and reduce API calls, implement a caching system:
const NodeCache = require('node-cache');
const Azbox = require('azbox-node');
const cache = new NodeCache({
stdTTL: 3600, // Cache for 1 hour
checkperiod: 600 // Check for expired keys every 10 minutes
});
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID
});
async function getCachedTranslation(keyword, lang = 'en') {
const cacheKey = `${keyword}_${lang}`;
// Check cache first
let translation = cache.get(cacheKey);
if (!translation) {
try {
// Fetch from API if not in cache
translation = await azbox.translate(keyword, lang);
// Store in cache
cache.set(cacheKey, translation);
} catch (error) {
console.error('Error fetching translation:', error);
return keyword; // Fallback to keyword
}
}
return translation;
}
async function getCachedTranslations(lang = 'en') {
const cacheKey = `all_${lang}`;
let translations = cache.get(cacheKey);
if (!translations) {
try {
translations = await azbox.getTranslations(lang);
cache.set(cacheKey, translations);
} catch (error) {
console.error('Error fetching translations:', error);
return {};
}
}
return translations;
}
// Usage
async function example() {
const translation = await getCachedTranslation('welcome', 'es');
console.log(translation);
const allTranslations = await getCachedTranslations('es');
console.log(allTranslations);
}
Don’t forget to install node-cache:
npm install node-cache
Step 11: Advanced Caching with Invalidation
For production applications, you may want to implement cache invalidation when translations are updated:
const NodeCache = require('node-cache');
const Azbox = require('azbox-node');
const cache = new NodeCache({
stdTTL: 3600,
checkperiod: 600
});
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID
});
// Function to invalidate cache for a specific language
function invalidateLanguageCache(lang) {
const keys = cache.keys();
keys.forEach(key => {
if (key.startsWith(`all_${lang}`) || key.endsWith(`_${lang}`)) {
cache.del(key);
}
});
}
// Function to invalidate cache for a specific keyword
function invalidateKeywordCache(keyword) {
const keys = cache.keys();
keys.forEach(key => {
if (key.startsWith(`${keyword}_`)) {
cache.del(key);
}
});
}
// Function to clear all cache
function clearAllCache() {
cache.flushAll();
}
// Webhook endpoint to receive cache invalidation events from Azbox
app.post('/webhooks/azbox-update', (req, res) => {
const { event, data } = req.body;
if (event === 'translation.updated') {
// Invalidate cache for the updated keyword and language
invalidateKeywordCache(data.keyword);
invalidateLanguageCache(data.language);
} else if (event === 'project.updated') {
// Clear all cache if entire project is updated
clearAllCache();
}
res.status(200).json({ success: true });
});
Step 12: TypeScript Support
If you’re using TypeScript, you can add type definitions for better type safety:
types/azbox.d.ts:
declare module 'azbox-node' {
interface AzboxConfig {
apiKey: string;
projectId: string;
}
interface TranslationOptions {
args?: string[];
namedArgs?: Record<string, string>;
}
class Azbox {
constructor(config: AzboxConfig);
translate(
keyword: string,
language?: string,
options?: TranslationOptions
): Promise<string>;
getTranslations(language?: string): Promise<Record<string, string>>;
getMultipleTranslations(
keywords: string[],
language?: string
): Promise<Record<string, string>>;
}
export default Azbox;
}
Usage with TypeScript:
import Azbox from 'azbox-node';
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY!,
projectId: process.env.AZBOX_PROJECT_ID!
});
async function getTranslation(): Promise<string> {
const translation = await azbox.translate('welcome', 'es');
return translation;
}
Best Practices
1. Always Use Environment Variables
Never hardcode your API keys in your source code. Always use environment variables:
// ❌ Bad
const azbox = new Azbox({
apiKey: 'sk_live_1234567890',
projectId: 'proj_1234567890'
});
// ✅ Good
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID
});
2. Implement Proper Error Handling
Always handle errors gracefully and provide fallbacks:
async function safeTranslate(keyword, lang) {
try {
return await azbox.translate(keyword, lang);
} catch (error) {
console.error('Translation error:', error);
// Fallback to keyword or default language
return keyword;
}
}
3. Use Caching for Production
Implement caching to reduce API calls and improve performance:
// Cache translations for at least 1 hour
const cache = new NodeCache({ stdTTL: 3600 });
4. Load Translations at Application Start
For better performance, consider loading all translations at application startup:
let translationsCache = {};
async function initializeTranslations() {
const languages = ['en', 'es', 'fr', 'de'];
for (const lang of languages) {
try {
translationsCache[lang] = await azbox.getTranslations(lang);
} catch (error) {
console.error(`Failed to load translations for ${lang}:`, error);
}
}
}
// Call on application start
initializeTranslations();
5. Use Middleware for Language Detection
Implement middleware to automatically detect and set the user’s language:
app.use(async (req, res, next) => {
// Detect language from:
// 1. Query parameter
// 2. Accept-Language header
// 3. Cookie
// 4. Default to 'en'
const lang =
req.query.lang ||
req.headers['accept-language']?.split(',')[0]?.split('-')[0] ||
req.cookies?.lang ||
'en';
req.lang = lang;
req.translations = await getCachedTranslations(lang);
next();
});
Common Use Cases
REST API with Translations
app.get('/api/products', async (req, res) => {
const products = await getProducts();
const lang = req.lang || 'en';
const translatedProducts = products.map(product => ({
...product,
name: await azbox.translate(`product_${product.id}_name`, lang),
description: await azbox.translate(`product_${product.id}_description`, lang)
}));
res.json(translatedProducts);
});
Email Templates with Translations
async function sendWelcomeEmail(userEmail, userName, userLang) {
const subject = await azbox.translate('email_welcome_subject', userLang);
const body = await azbox.translate('email_welcome_body', userLang, {
namedArgs: { name: userName }
});
await sendEmail({
to: userEmail,
subject: subject,
body: body
});
}
CLI Application with Translations
const readline = require('readline');
const Azbox = require('azbox-node');
const azbox = new Azbox({
apiKey: process.env.AZBOX_API_KEY,
projectId: process.env.AZBOX_PROJECT_ID
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
async function askQuestion(keyword, lang) {
const question = await azbox.translate(keyword, lang);
return new Promise(resolve => {
rl.question(question, answer => {
resolve(answer);
});
});
}
async function main() {
const lang = process.argv[2] || 'en';
const name = await askQuestion('cli_ask_name', lang);
const greeting = await azbox.translate('cli_greeting', lang, {
namedArgs: { name }
});
console.log(greeting);
rl.close();
}
main();
Troubleshooting
Issue: “KEYWORD_NOT_FOUND” Error
Problem: The keyword doesn’t exist in your Azbox project.
Solution:
- Check that the keyword exists in your Azbox dashboard
- Verify the keyword spelling matches exactly
- Ensure the keyword is published (not in draft)
Issue: “LANGUAGE_NOT_FOUND” Error
Problem: The requested language is not available in your project.
Solution:
- Check available languages in your Azbox project settings
- Use a fallback to the default language
- Verify the language code format (e.g., ‘es’, ‘en’, ‘fr’)
Issue: API Rate Limiting
Problem: Too many API requests causing rate limit errors.
Solution:
- Implement caching to reduce API calls
- Batch requests using
getMultipleTranslations() - Load all translations at startup instead of on-demand
Issue: Slow Response Times
Problem: Translation API calls are slow.
Solution:
- Implement caching with
node-cache - Preload translations at application startup
- Use
getTranslations()to load all translations at once instead of individual calls
Next Steps
- Check the complete Azbox Node.js SDK documentation
- Explore the azbox-node package on npm
- Set up webhooks for real-time translation updates
- Implement translation fallbacks for missing keywords
- Consider using TypeScript for better type safety
- Set up monitoring and logging for translation API calls
Conclusion
Integrating Azbox into your Node.js backend application provides a powerful and flexible solution for managing translations. By following this guide, you can:
- Set up Azbox in your Node.js application
- Implement efficient translation retrieval
- Handle errors gracefully
- Optimize performance with caching
- Support multiple languages seamlessly
Start adding translations to your Node.js application today and reach a global audience!