
- ESX
- Standalone
- QBCore
- vRP
By Luke

A current FiveM loading screen is an NUI resource declared with loadscreen in fxmanifest.lua. Keep the first version local and small: one HTML document, one stylesheet and one script. Add progress or server handover data only after the basic screen opens and closes correctly.
The configuration and code examples here target FiveM for GTA V Legacy. Enhanced has different runtime and compatibility rules; check Cfx.re’s Legacy-to-Enhanced changes before applying them to an Enhanced server.
Back up the existing resource and keep the default automatic shutdown first. A broken manual-shutdown script can leave players looking at the loading screen after the game is ready.
resources/[local]/my_loadscreen/
├── fxmanifest.lua
└── html/
├── index.html
├── style.css
└── app.js
fxmanifest.lua:
fx_version 'cerulean'
game 'gta5'
author 'Your name'
description 'FiveM loading screen'
version '1.0.0'
loadscreen 'html/index.html'
files {
'html/index.html',
'html/style.css',
'html/app.js'
}
New resources should use fxmanifest.lua. Do not add a legacy __resource.lua fallback. The directives are defined in the official resource manifest reference.
html/index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Connecting to Example RP</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<h1>Connecting to Example RP</h1>
<progress id="progress" value="0" max="1" aria-label="Loading progress"></progress>
<p id="status" aria-live="polite">Loading server resources…</p>
</main>
<script src="app.js"></script>
</body>
</html>
Use text that remains readable over the background, respects reduced motion and does not depend on autoplay audio. Compress images and video before packaging them; every client has to download the resource.
Save this as html/style.css; it supplies the stylesheet referenced by the HTML:
body { margin: 0; min-height: 100vh; display: grid; place-items: center;
background: #15212b; color: #fff; font: 20px/1.6 system-ui; }
main { width: min(620px, 85vw); }
progress { width: 100%; height: 20px; accent-color: #6cd6ba; }html/app.js:
const progress = document.getElementById('progress');
const status = document.getElementById('status');
window.addEventListener('message', (event) => {
if (event.data?.eventName !== 'loadProgress') return;
const value = Number(event.data.loadFraction);
if (!Number.isFinite(value)) return;
const clamped = Math.max(0, Math.min(1, value));
progress.value = clamped;
status.textContent = `Loading ${Math.round(clamped * 100)}%`;
});
The official Cfx.re loading-screen guide documents loadProgress and the other events exposed to this NUI frame. Treat event data as input and update text with textContent, not innerHTML.
A server-side playerConnecting handler can pass small values with deferrals.handover. FiveM exposes them as window.nuiHandoverData. Use this for display values such as a player name; never include secrets, tokens, private identifiers or data that grants an entitlement. Insert player-controlled values with textContent or innerText.
If the screen must fade out after client scripts start, add these lines:
loadscreen_manual_shutdown 'yes'
client_script 'client.lua'
The example below closes it from client.lua when the network session starts. If your framework requires character selection first, use its documented ready signal instead:
CreateThread(function()
while not NetworkIsSessionStarted() do
Wait(100)
end
ShutdownLoadingScreenNui()
end)
Test reconnects, resource restarts and a slow client. If the screen can remain stuck, remove loadscreen_manual_shutdown and the client script to return to automatic lifecycle handling.
ensure my_loadscreen to the intended point in server.cfg.refresh and ensure my_loadscreen on a development server.

0Resmon



