The FiveM Server Launch Handbook
Everything between “the server runs” and “the server is full” in one place: how players find you in the server list, what they see while connecting, a loading screen that loads fast and looks like your brand, the NUI that follows it, your Discord, website and videos, how to make money within the rules, a launch plan, and how to keep the players you win. Every chapter has working config and code, and links to a detailed guide.
- chapters
- 18
- reading time
- 60 min
- settings & events
- 25
- glossary terms
- 24
Who this handbook is for
- Owners preparing a server launch or relaunch
- Developers building loading screens and NUI
- Community managers running Discord, rules and staff
- Anyone who wants more players to join — and stay
Updated 11 September 2026 · checked against the official Cfx.re documentation
Launch-ready in an afternoon
- 1Set
sets sv_projectName,sets sv_projectDesc,sets tagsandsets localein server.cfg. - 2Add a 96×96 PNG with
load_server_icon logo96.pngand wide banners withsets banner_detail/sets banner_connecting. - 3Replace the framework’s loading screen with your own — one resource with
loadscreen 'index.html'in its manifest. - 4Add a WebM background, your logo, a progress bar, rules and your Discord link.
- 5Share
https://cfx.re/join/<code>everywhere and set up Discord with rules, tickets and roles. - 6Pick a launch time, brief staff, and follow the launch checklist.
The player journey: from server list to first minute
A new player decides in a few minutes whether your server is worth their evening. Every step of that path is something you control.
| Step | What the player sees | What you control |
|---|---|---|
| Server list | Name, icon, tags, player count | sv_projectName, icon, tags, locale — listing |
| Server page | Description and detail banner | sv_projectDesc, banner_detail — banners |
| Connecting | Connecting banner, cards, queue position | banner_connecting, deferrals — connecting |
| Loading screen | Your brand, progress, rules, music | The loadscreen resource — loading screens |
| Spawn | Character select, first location | Multicharacter and spawn scripts |
| First minute | HUD, minimap, someone to talk to | NUI, staff presence, a guided start |
Fix the path from the top down: a broken listing hides everything else, and a slow or ugly loading screen loses players before they ever spawn. Growth strategy: grow your server.
Getting listed: name, description, tags, locale and icon
The server list is your shop window. Two convars are required to be listed at all; the rest decide whether anyone clicks.
sv_hostname "Night City RP"
sets sv_projectName "^5Night City^7 RP"
sets sv_projectDesc "Serious roleplay with custom jobs, player-run businesses and weekly events."
sets tags "roleplay, serious, economy, jobs, custom cars"
sets locale "en-US"
load_server_icon logo96.png
# whitelisted servers
sets sv_appearAllowlisted true
sets sv_allowlistInstructions "Apply on discord.gg/example"| Setting | Rule |
|---|---|
sv_projectName | Required. A name, not a list of features — non-compliant names are cut off |
sv_projectDesc | Required. One sentence about why the server is worth joining |
tags | Comma-separated; how players filter the list |
locale | Your main language, e.g. en-US — never leave the default root-AQ |
| Icon | Exactly 96×96, a real PNG |
| Colour codes | ^1 red, ^2 green, ^3 yellow, ^4 blue, ^5 light blue, ^6 purple, ^7/^0 reset |
Connecting: deferrals, adaptive cards, queues and whitelists
While a player connects, the server can hold them, show progress, ask questions with a card, check a whitelist or place them in a queue — all through deferrals.
AddEventHandler('playerConnecting', function(name, setKickReason, deferrals)
local src = source
deferrals.defer()
Wait(0)
deferrals.update(('Checking your whitelist, %s…'):format(name))
local license = GetPlayerIdentifierByType(src, 'license')
if not license or not IsWhitelisted(license) then
return deferrals.done('Not whitelisted — apply on discord.gg/example')
end
deferrals.handover({ name = name })
deferrals.done()
end)| Call | Does |
|---|---|
deferrals.defer() | Hold the connection (then wait at least one tick) |
deferrals.update(text) | Show a progress message |
deferrals.presentCard(card, cb) | Show an Adaptive Card with inputs and buttons |
deferrals.handover(data) | Pass data to the loading screen |
deferrals.done() / done(reason) | Let them in, or refuse with a reason |
- Every code path must end in
deferrals.done— or players hang on “connecting”. - Queues hold players in deferrals, sort by priority and join time, and update positions every few seconds.
- Whitelists usually check a Discord role through the bot API, cached briefly.
- Design cards at adaptivecards.io and stick to simple 1.x elements.
Join links: cfx.re/join and fivem://
One link that opens FiveM and connects is the single most useful thing you can put in every post, video and profile.
| Where | Use |
|---|---|
| Anywhere | https://cfx.re/join/<code> |
| Website “Play” button | fivem://connect/cfx.re/join/<code> |
| F8 console | connect cfx.re/join/<code> or connect ip:port |
How FiveM loading screens work
A loading screen is a resource whose manifest declares a loadscreen page. It appears while the game loads your server’s content and closes when loading finishes — or when a script says so.
fx_version 'cerulean'
game 'gta5'
loadscreen 'index.html'
loadscreen_cursor 'yes'
loadscreen_manual_shutdown 'yes'
files {
'index.html',
'style.css',
'script.js',
'assets/*',
}| Setting | Effect |
|---|---|
loadscreen 'index.html' | The page to show; only one running resource may declare it |
loadscreen_cursor 'yes' | Shows the mouse so buttons work |
loadscreen_manual_shutdown 'yes' | Stays up until a client script calls ShutdownLoadingScreenNui() |
files { … } | Every file the page uses must be listed |
- Replacing a framework screen: stop
qb-loadingscreenoresx_loadingscreen, thenensureyours. - With manual shutdown, the multicharacter or spawn script closes the screen — always keep a fallback so nobody is stuck.
- Links do not navigate the screen; open them in the player’s browser with
window.invokeNative('openUrl', url).
Building the loading screen: HTML or React
Plain HTML, CSS and JavaScript are enough for a great loading screen. React with Vite is worth it when the screen has tabs, carousels and state.
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<video class="bg" src="assets/bg.webm" poster="assets/poster.webp" autoplay muted loop playsinline></video>
<main class="panel">
<img class="logo" src="assets/logo.png" alt="Night City RP" />
<p id="status">Loading…</p>
<div class="bar"><span id="fill"></span></div>
</main>
<audio id="music" src="assets/music.mp3" autoplay loop></audio>
<script src="script.js"></script>
</body>
</html>const fill = document.getElementById('fill');
const status = document.getElementById('status');
const music = document.getElementById('music');
let shown = 0;
music.volume = Number(localStorage.getItem('vol') ?? 0.3);
window.addEventListener('message', (e) => {
const d = e.data;
if (d.eventName === 'loadProgress') {
shown = Math.max(shown, d.loadFraction); // never go backwards
fill.style.width = `${Math.round(shown * 100)}%`;
}
if (d.eventName === 'onLogLine') status.textContent = d.message;
});
const data = window.nuiHandoverData || {};
if (data.name) status.textContent = `Welcome, ${data.name}`;- React + Vite: set
base: './'so asset paths are relative, pointloadscreenat the builtindex.htmland list the build folder infiles. - Mock the loading messages during
npm run devso you can design in a normal browser. - Handover data is visible to the player — send small, non-sensitive values only.
Backgrounds, video, music and fonts
Media makes a loading screen feel alive — and is also what makes it slow. Pick formats the in-game browser plays reliably and keep files small.
| Media | Use | Why |
|---|---|---|
| Video | WebM (VP9/VP8), 1920×1080, 24–30 fps, 10–30 MB, no audio track | H.264 cannot be relied on in FiveM’s browser |
| Images | WebP at display size | Small and sharp |
| Music | MP3, start at volume ~0.3 with a mute button | The loading screen may autoplay with sound |
| Fonts | WOFF2, listed in files, loaded with @font-face | Small and reliable |
| YouTube | Full-screen iframe with autoplay, loop, playlist=VIDEO_ID, controls off | Use videos you own or may embed |
Everything bundled in the resource downloads before the screen appears, so large videos belong on a CDN. Budget: a few megabytes before the video.
Designing a loading screen people like
One focal point, readable text, your brand colours and only the information a waiting player wants.
| Show | How |
|---|---|
| Progress | A bar that never goes backwards, plus a status line |
| Top rules | Three to five lines; full rules behind a tab |
| Tips | 15–40 one-sentence tips, 7–9 seconds each |
| Staff | Small cards with Discord avatars, behind a tab |
| Discord link | A button that opens with invokeNative('openUrl', …) |
| Events | A seasonal theme switched by date |
.bg { position: fixed; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.panel {
position: fixed; left: 50%; bottom: 8vh; transform: translateX(-50%);
width: min(640px, 90vw); padding: 1.25rem 1.5rem; border-radius: 14px;
background: rgba(8, 8, 12, 0.72); color: #f5f5f7;
}
.panel p { font-size: clamp(14px, 1.1vw, 20px); }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; } }- Design at 1920×1080, keep important content in a centred safe area, and test at 1440p and 4K.
- Use solid semi-transparent panels, not
backdrop-filterblur. - Live player counts need an HTTPS source you control — the server’s
/dynamic.jsonis plain HTTP and gets blocked. - Running several servers? One screen, per-server convars passed with handover data.
NUI essentials: pages, messages, callbacks and focus
After the loading screen, every HUD, menu and phone is NUI: a page in the in-game browser that talks to Lua.
| Direction | Lua | Page |
|---|---|---|
| Lua → page | SendNUIMessage({ action = 'open', data = … }) | window.addEventListener('message', e => e.data) |
| Page → Lua | RegisterNuiCallback('name', function(data, cb) cb({ ok = true }) end) | fetch(https://${GetParentResourceName()}/name, …) |
| Input | SetNuiFocus(true, true) / SetNuiFocus(false, false) | Close on Escape and tell Lua |
| Files | ui_page + files | Relative paths; https://cfx-nui-<resource>/… for other resources |
- Always call
cbin NUI callbacks — even on errors — or the page’s fetch never resolves. - Release focus on every close path and when the resource stops.
- Match file-name case exactly — Linux servers are case-sensitive.
- React:
useNuiEvent,fetchNui, mockeddebugDataandisEnvBrowser()make browser development painless.
Deeper patterns for developers: NUI to Lua communication and the FiveM Developer Handbook.
NUI quality: browser limits, performance, debugging and HUDs
The in-game browser is Chromium with a few gaps. Knowing them saves days of “works in Chrome, broken in game”.
| Limitation | Workaround |
|---|---|
backdrop-filter unreliable | Solid semi-transparent colours |
| H.264 not dependable | WebM video |
Links and window.open do nothing | window.invokeNative('openUrl', url) |
alert and native dialogs useless | Your own modal |
| Async clipboard often fails | Show the text to copy manually |
- Debug at
http://localhost:13172/in a Chromium browser while the game runs, ornui_devToolsin F8 (developer mode). - Send messages only on change; throttle speed and fuel to a few updates per second.
- Animate only
transformandopacity; hide closed UIs withdisplay: none. - HUDs: show only what matters now, anchor to the minimap, respect
GetSafeZoneSize(), hide whenIsPauseMenuActive(). - One notification resource for everything, so ESX, QBCore and ox_lib toasts look the same.
Branding: logo, kit, pause menu and rich presence
The same logo, colours and fonts on the server list, loading screen, HUD, Discord and videos make a small server look established.
CreateThread(function()
AddTextEntry('FE_THDR_GTAO', '~p~Night City RP~s~ | discord.gg/example')
ReplaceHudColourWithRgba(116, 124, 92, 255, 255)
SetDiscordAppId('123456789012345678')
SetDiscordRichPresenceAsset('logo')
SetDiscordRichPresenceAction(0, 'Join the server', 'https://cfx.re/join/abc123')
SetDiscordRichPresenceAction(1, 'Discord', 'https://discord.gg/example')
SetRichPresence('Roleplaying in Night City')
end)- Kit first: name, logo (full + compact mark), one accent colour, one or two fonts.
- The compact mark must read at 96×96 and inside a circle.
- Keep masters in one shared folder with a one-page brand guide.
- Avoid GTA/Rockstar logos — they are trademarks and imply endorsement.
In-game touches that carry the brand: a themed minimap and branded weapon skins.
Discord, rules and staff
Discord is where players decide to stay, get help, apply and hear about events. Structure it like a product, not a chat room.
| Category | Channels |
|---|---|
| Start here | welcome, rules, how-to-join, announcements |
| Server info | updates, events, jobs, store |
| Community | general, clips, screenshots, looking-for-group |
| Support | tickets, appeals, bug reports |
| Staff | staff-chat, logs, reports |
- Community mode for onboarding and rules screening; permissions on roles, not people.
- Rules in numbered sections with defined terms (RDM, VDM, metagaming, powergaming, NLR) and a punishment ladder.
- Staff ladder: trial support → support → moderator → admin → head admin → owner, each with only the permissions it needs.
- Whitelist applications answered within a day or two, with automatic access through a Discord role.
Website, trailer and short-form video
Players discover servers through clips and search. A small website and a steady stream of short videos do more than any paid ad.
| Channel | What works |
|---|---|
| Website | Trailer, Play button (fivem://connect/cfx.re/join/<code>), rules, guides, applications, store and Discord links |
| Trailer | 60–90 s: hook, world, jobs and systems, community, call to action |
| TikTok / Shorts | 15–45 s vertical clips of real moments, hook in two seconds, captions, several a week |
| YouTube | Tours, update showcases, longer stories |
| Creators | Small creators who fit your style, one Discord link for everyone |
Export the trailer as a 16:9 master and a short WebM loop — the loop doubles as your loading screen background.
Monetization the allowed way
Tebex is Cfx.re’s authorized monetization partner. Using any other platform or payment provider to monetize a server is prohibited under the Platform License Agreement.
- 1Create a Tebex store and complete identity verification.
- 2Link your Cfx.re account and connect the server with
sv_tebexSecretin server.cfg. - 3Design packages that feel fair and pass Tebex’s review.
- 4Read the current Platform License Agreement and Tebex policies for what may be sold.
The launch plan
A launch is a date, not a hope. Work backwards from it.
| When | Do |
|---|---|
| Two weeks out | Hosting, security, backups and restarts; performance test with 20+ players |
| One week out | Listing, loading screen, Discord and rules, trained staff, store live |
| Launch day | A fixed time, staff on duty, announcements ready, clips recorded |
| First week | Fix the top complaints fast; run events every day |
sv_projectName,sv_projectDesc, tags, locale and a 96×96 icon- Banners on permanent HTTPS links
- Your own loading screen, under a few MB before the video, tested at 1080p and 4K
- Music you have the rights to, with a mute button
- Deferrals that always end in
done; queue and whitelist tested - cfx.re/join link in Discord, website, bios and videos
- Discord with rules, tickets, roles and a welcome flow
- Staff briefed with written guidelines
- Tebex store connected and reviewed
- Trailer and five short clips ready to post
Growth and retention
Growth is three loops: discovery, the first experience, and reasons to come back. Measure the second and third before paying for the first.
| Loop | Levers |
|---|---|
| Discovery | Listing, clips, creators, word of mouth |
| First experience | Fast join, clear loading screen, a guided start, someone to talk to |
| Retention | Goals and progression, groups, events, updates, fair moderation, smooth performance |
Track how many new players return after one day and after one week — txAdmin’s player database has first and last join times. Ask leavers why, and fix patterns rather than single complaints.
Loading screen troubleshooting
Almost every loading screen problem is one of these.
| Symptom | Cause | Fix |
|---|---|---|
| Default screen still shows | Another resource declares loadscreen | Stop the framework’s loading screen |
| Blank or white screen | A file is missing from files, or a path is wrong | List every file; use relative paths |
| Stuck after loading | loadscreen_manual_shutdown without a shutdown call | Call ShutdownLoadingScreenNui() from your spawn script, with a fallback |
| Music does not play | Wrong path, unsupported format, or volume 0 | MP3, listed in files, set audio.volume |
| Video does not play | H.264 or a huge file | WebM, 10–30 MB, or a CDN |
| Changes do not show | Client cache | Restart the resource; players clear FiveM cache |
| Fonts fall back | Font file not in files or wrong path | WOFF2, listed, relative @font-face URL |
| Links do nothing | Loading screen cannot navigate | window.invokeNative('openUrl', url) |
Cheat sheets
Loading screen manifest keys
In the loading screen resource’s fxmanifest.lua.
| Key | Effect |
|---|---|
loadscreen 'index.html' | Declares the page |
loadscreen_cursor 'yes' | Shows the mouse |
loadscreen_manual_shutdown 'yes' | Waits for ShutdownLoadingScreenNui() |
files { … } | Every file the page loads |
Loading screen messages
Received with `window.addEventListener('message', …)` as `e.data.eventName`.
| eventName | Carries |
|---|---|
loadProgress | loadFraction from 0 to 1 |
startInitFunctionOrder | count of init functions |
initFunctionInvoking | idx of the current one |
startDataFileEntries | count of map data files |
performMapLoadFunction | Fires per map file |
onLogLine | message — a status line to show |
window.nuiHandoverData | Your handover values, plus serverAddress |
Server list settings
In server.cfg.
| Setting | Example |
|---|---|
sets sv_projectName | "Night City RP" |
sets sv_projectDesc | "Serious roleplay with…" |
sets tags | "roleplay, economy" |
sets locale | "en-US" |
load_server_icon | logo96.png (96×96 PNG) |
sets banner_detail / banner_connecting | "https://…/banner.png" |
sets sv_appearAllowlisted | true |
sets sv_allowlistInstructions | "Apply on discord.gg/…" |
NUI at a glance
Lua on the left, page on the right.
| Lua | Page |
|---|---|
SendNUIMessage(table) | message event, e.data |
RegisterNuiCallback(name, fn) | fetch('https://<resource>/<name>') |
SetNuiFocus(focus, cursor) | — |
SetNuiFocusKeepInput(true) | Walk while the UI is open |
| — | window.invokeNative('openUrl', url) |
| — | GetParentResourceName() |
Glossary
- Adaptive Card
- A JSON-defined card with inputs and buttons, shown while connecting with
deferrals.presentCard. - Banner
- A wide image shown on the server page (
banner_detail) or while connecting (banner_connecting). - CEF
- The embedded Chromium browser FiveM uses for NUI and loading screens.
- cfx.re/join
- A short link that opens FiveM and connects to a listed server.
- Deferrals
- The
playerConnectingAPI for holding, updating, checking and admitting players. - Focus
- Whether NUI receives keyboard and mouse, set with
SetNuiFocus. - Handover data
- Values passed from
deferrals.handovertowindow.nuiHandoverDatain the loading screen. - Locale
- The server’s main language in the list, e.g.
en-US. - loadProgress
- The loading screen message carrying
loadFractionfrom 0 to 1. - Loading screen
- The page shown while the game loads the server’s content.
- Manual shutdown
- Keeping the loading screen up until
ShutdownLoadingScreenNui()is called. - NUI
- The in-game browser layer for HUDs, menus and loading screens.
- NUI callback
- A Lua handler the page calls with
fetch('https://<resource>/<name>'). - PLA
- The Cfx.re Platform License Agreement, which sets monetization rules.
- Queue
- A resource that holds players in deferrals until a slot is free.
- Rich presence
- The status and buttons shown on a player’s Discord profile.
- Safe zone
- The screen area HUD elements must stay inside, from
GetSafeZoneSize(). - sv_projectName
- The required community name shown in the server list.
- sv_projectDesc
- The required one-sentence description in the server list.
- Tags
- Comma-separated keywords players filter the server list by.
- Tebex
- Cfx.re’s authorized monetization partner.
- WebM
- The video format to use in FiveM’s browser (VP9 or VP8).
- Whitelist
- Allowing only approved players, usually through a Discord role check at connect.
- WOFF2
- The compact web font format to ship with a loading screen.
Questions server owners ask
How do I make a custom FiveM loading screen?
Create a resource with an fxmanifest.lua that declares loadscreen 'index.html' and lists every file, build the page in HTML/CSS/JS, stop your framework’s loading screen and ensure yours.
Why does my loading screen not show?
Another resource still declares loadscreen, the resource is not started, or a file is missing from files.
How do I add music to a FiveM loading screen?
Use an <audio autoplay loop> element with an MP3 listed in files, set audio.volume in JavaScript and add a mute button.
What video format should a loading screen use?
WebM (VP9 or VP8) at 1920×1080 and 24–30 fps, ideally 10–30 MB or hosted on a CDN.
How do I show a real loading progress bar?
Listen for the loadProgress message and use its loadFraction (0–1), never letting the displayed value go backwards.
Why are players stuck on the loading screen?
Usually loadscreen_manual_shutdown is on but no script calls ShutdownLoadingScreenNui().
What size is the FiveM server icon?
96×96 pixels, PNG, loaded with load_server_icon.
What size should FiveM server banners be?
There is no official size; wide strips like 1865×108 or 1920×200 are common. Keep text in the middle.
Why is my server not in the server list?
Missing sv_projectName/sv_projectDesc, closed ports, an active sv_master1, or it has not been 8 minutes yet.
How do I get a cfx.re/join link?
Open your server in the server browser; the code at the end of its page URL goes into https://cfx.re/join/<code>.
How do I add a queue to my FiveM server?
Use a queue resource that holds players in playerConnecting deferrals and admits them by priority when a slot frees up.
Can I monetize my FiveM server with PayPal or Stripe directly?
No — Tebex is Cfx.re’s authorized monetization partner, and using other platforms to monetize a server is prohibited under the PLA.
Can I use copyrighted music on my loading screen?
Not without a licence. Use royalty-free music whose licence covers it, a commissioned track, or your own.
How do I open a link from the loading screen?
Enable loadscreen_cursor and call window.invokeNative('openUrl', 'https://…').
How do I grow a FiveM server?
Fix the first experience, post short clips of real moments, run Discord as your hub, keep events and updates coming, and measure who returns after a day and a week.
Do I need a website for my FiveM server?
A small one helps: trailer, Play button, rules, applications, store and Discord links, with basic SEO.
Official references
Official documentation
- Server commands (listing convars) — sv_projectName, tags, icon
- Server issues — Server list troubleshooting
- Resource manifest — loadscreen, files, ui_page
- Natives reference — NUI, rich presence, text entries
- Featured server list — Promotion options
Platforms
- Cfx.re Portal — Keys and subscriptions
- Adaptive Cards Designer — Design connecting cards
- Discord Developer Portal — Rich presence applications
- Tebex — Authorized monetization partner
Community
- Cfx.re forum — Releases and help
The FiveM Handbook series
Four free handbooks, one per part of the job.
Skip the HTML — build your loading screen in the browser
Templates, video and music, rules, staff and tips widgets — export once and edit it whenever.
Start free