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:8080

With a test key you see sample listings. Swap in a live key and the same two files show the real directory.