Showing a live player count on your loading screen
The FiveM server reports its player count at /dynamic.json (clients and sv_maxclients). A loading screen usually cannot fetch it directly: the page is served securely and the server endpoint is plain HTTP on port 30120, so the request is blocked as mixed content (and may lack CORS headers). Serve the count from an HTTPS URL you control — a reverse proxy, or a small resource using SetHttpHandler behind HTTPS — or send it once with deferrals.handover.
“84 / 128 players online” on the loading screen is powerful social proof: it tells a new player the city is alive before they have seen it. Getting that number is easy on paper — the server publishes it — but browsers have rules about where a page may fetch data from, and a loading screen is a page. Here is how to do it so it actually works in game.
What the server publishes
| Endpoint | Contains |
|---|---|
/dynamic.json | hostname, clients (online now), sv_maxclients, game type and map |
/info.json | Server variables, resources and version information |
/players.json | One entry per player — anonymised unless the request carries sv_playersToken |
Current FiveM servers no longer expose players’ addresses on any of these endpoints (the old sv_endpointPrivacy setting was removed for that reason), and player names and identifiers appear on /players.json only when the request is authenticated with the server’s sv_playersToken. For a count, /dynamic.json is all you need.
Why a direct fetch fails in game
- 1Mixed content: modern (cerulean) loading screens and hosted ones run on secure origins. A request from a secure page to
http://1.2.3.4:30120/dynamic.jsonis blocked by the browser engine. - 2CORS: even over HTTPS, the response must allow your page’s origin to read it.
- 3Exposure: publishing your server’s raw IP inside a loading screen hands it to everyone who opens the file.
Option 1: a small HTTP resource
Resources can answer HTTP requests at http://your-server:30120/<resourceName>/… with SetHttpHandler. Return just the numbers, with a CORS header, and put HTTPS in front of the server with a reverse proxy and a domain.
SetHttpHandler(function(req, res)
if req.path == '/count' then
res.writeHead(200, {
['Content-Type'] = 'application/json',
['Access-Control-Allow-Origin'] = '*',
['Cache-Control'] = 'max-age=10',
})
res.send(json.encode({
online = #GetPlayers(),
max = GetConvarInt('sv_maxclients', 48),
}))
return
end
res.writeHead(404)
res.send('')
end)async function refreshCount() {
try {
const r = await fetch('https://play.mycity.gg/online/count', { cache: 'no-store' });
const { online, max } = await r.json();
document.getElementById('online').textContent = `${online} / ${max} online`;
} catch { /* keep the last value */ }
}
refreshCount();
setInterval(refreshCount, 15000);The HTTPS address in the example is your reverse proxy forwarding to the server’s port 30120. A short Cache-Control keeps a hundred loading screens from hammering the server.
Option 2: handover (no infrastructure)
Send the count once while the player connects with deferrals.handover({ online = #GetPlayers() }) and read window.nuiHandoverData.online. It is not live, but it is accurate at the moment they joined and needs nothing extra — see handover data.
Option 3: a hosted widget
Hosted loading screen builders can fetch the count on their own servers and show it as a widget, which avoids the mixed-content and CORS work entirely. Our builder’s player-count widget works this way.
Common questions
How do I get the player count of a FiveM server?
The server’s /dynamic.json endpoint returns clients (players online) and sv_maxclients.
Why does fetching dynamic.json fail from my loading screen?
The loading screen runs on a secure origin and the server endpoint is plain HTTP, so the browser blocks it as mixed content. Serve the count over HTTPS with CORS allowed.
Can I show player names on the loading screen?
Public /players.json is anonymised. Names require the server’s sv_playersToken, which must never be put in client-side code — so do it through your own backend if at all.
Is sv_endpointPrivacy still needed?
No. It has been removed; current servers no longer expose player addresses on HTTP endpoints.
Want a loading screen you never have to debug?
Build it in the browser, export once, and edit it whenever — no HTML, no re-uploads.
Start free