Sample page
A whole integration in two small files: a server that holds the key and caches, and a page that shows this week’s top games and the newest games from one country.
What it does
- Keeps the key on the server. The browser never sees it.
- Caches each answer for ten minutes, so a busy page makes six calls an hour.
- Falls back to the last good answer when the API is unreachable.
The server
server.mjs · Node 18+, no packages
import http from "node:http";
import fs from "node:fs";
const API = "https://developers.arena54.com/api/v1";
const KEY = process.env.A54_KEY; // a54_test_… while you build
const cache = new Map(); // path -> { at, data }
async function get(path) {
const hit = cache.get(path);
if (hit && Date.now() - hit.at < 600_000) return hit.data;
try {
const res = await fetch(API + path, { headers: { Authorization: `Bearer ${KEY}` } });
const body = await res.json();
if (!body.success) throw new Error(body.error.code);
cache.set(path, { at: Date.now(), data: body.data });
return body.data;
} catch (e) {
if (hit) return hit.data; // serve the last good answer
throw e;
}
}
http.createServer(async (req, res) => {
const url = new URL(req.url, "http://x");
if (url.pathname === "/data") {
const country = (url.searchParams.get("country") || "NG").slice(0, 2).toUpperCase();
try {
const [top, fresh] = await Promise.all([get("/rankings/games/week?limit=5"), get(`/games?country=${country}&limit=6`)]);
res.writeHead(200, { "Content-Type": "application/json" }).end(JSON.stringify({ top, fresh }));
} catch {
res.writeHead(502).end("{}");
}
return;
}
res.writeHead(200, { "Content-Type": "text/html" }).end(fs.readFileSync("index.html"));
}).listen(8080);The page
index.html
<!doctype html>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Games made here</title>
<h1>Top games this week</h1>
<ol id="top"></ol>
<h2>New from Nigeria</h2>
<ul id="fresh"></ul>
<p><small>Data from <a href="https://arena54.com">Arena54</a></small></p>
<script type="module">
const { top, fresh } = await (await fetch("/data?country=NG")).json();
const row = (name, url, note) => {
const li = document.createElement("li");
const a = Object.assign(document.createElement("a"), { href: url, textContent: name });
li.append(a, note ? ` · ${note}` : "");
return li;
};
document.querySelector("#top").append(...top.map((r) => row(r.name, r.url, `${r.wins} wins`)));
document.querySelector("#fresh").append(...fresh.map((g) => row(g.title, g.url, g.creator.name)));
</script>Run it
Shell
A54_KEY=a54_test_… node server.mjs
# then open http://localhost:8080With a test key you see sample listings. Swap in a live key and the same two files show the real directory.