Integration guide
Add currency exchange rates and conversion to Express.js
Add server-side Express endpoints with the standard fetch client. Cache the latest response until nextUpdateAt to conserve quota.
1. Get a free API key
Sign up at https://currencyexchangerate-api.com/auth/login, then create a key under API keys in the console. The free plan includes 3,000 requests per month with no credit card. Store the secret as CXR_API_KEY in server-side environment configuration; never expose it in browser code.
.env
shellCXR_API_KEY=cxr_your_secret_key2. Create a reusable client and cache rates
Use the standard HTTP client. Cache every /latest response until nextUpdateAt: rates change at most once by then, and reusing the response saves quota. The helper also exposes /convert.
rates.js
JavaScriptconst API_BASE_URL = 'https://api.currencyexchangerate-api.com/api/v1';const key = process.env.CXR_API_KEY;const saved = new Map(); async function get(path) { const response = await fetch(API_BASE_URL + path, { headers: { Authorization: 'Bearer ' + key }, }); if (!response.ok) { throw new Error('Rates API status ' + response.status); } return response.json();} export async function latest(base = 'USD', symbols = 'EUR,GBP') { const id = base + ':' + symbols; const hit = saved.get(id); if (hit && Date.now() < hit.until) { return hit.data; } const query = new URLSearchParams({ base, symbols }); const data = await get('/latest?' + query); saved.set(id, { data, until: Date.parse(data.nextUpdateAt) }); return data;} export async function convert(from, to, amount) { const query = new URLSearchParams({ from, to, amount: String(amount) }); return get('/convert?' + query);}3. Use it in Express.js
Call the helper from a server route, controller, view, command, or script. Format converted values for the user’s locale.
app.js
JavaScriptimport express from 'express'; import { latest, convert } from './rates.js'; const app = express(); app.get('/api/rates', async (_req, res) => res.json(await latest())); app.get('/api/convert', async (req, res) => { const { from, to, amount } = req.query; const data = await convert(String(from), String(to), Number(amount)); res.json(data);}); app.listen(3000);4. Handle API errors
A 401 means the key is invalid. A 429 can mean a rate limit or quota limit; read Retry-After in seconds before retrying. Other errors use application/problem+json.
errors.js
JavaScript// In get(), replace the generic throw with:// if (!response.ok) throw await apiError(response);async function apiError(response) { const problem = await response.json().catch(() => ({})); if (response.status === 401) { return new Error('Check CXR_API_KEY'); } if (response.status === 429) { const retryAfter = response.headers.get('Retry-After'); return new Error('Retry after ' + retryAfter + ' seconds'); } return new Error(problem.detail || 'Rates API status ' + response.status);}5. Format the amount for display
Use locale-aware currency formatting instead of adding a symbol manually.
format.js
JavaScriptconst formatter = new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR',});const formatted = formatter.format(85.249105);