Showing Adaptive Cards while players connect
Design a card in the Adaptive Cards Designer (adaptivecards.io), export its JSON, and show it with deferrals.presentCard(card, function(data, rawData) ... end). Action.Submit buttons call your function with the input values (and the button’s id as submitId). Chain cards by calling presentCard again, and end with deferrals.done(). Stick to simple 1.x elements and test in game.
A plain “Checking whitelist…” line is fine, but deferrals can do more: they can show an Adaptive Card — a small layout with text, images, inputs and buttons — before the player loads. Servers use it for rule acceptance, Discord links, language choice or a server password.
Designing the card
Open the Adaptive Cards Designer, build your layout with TextBlock, Image, Input.Text, Input.ChoiceSet and ActionSet elements, and copy the card JSON. Keep images hosted on HTTPS and small.
Example: accept the rules
local card = {
type = 'AdaptiveCard',
version = '1.0',
body = {
{ type = 'TextBlock', text = 'Welcome to Los Santos RP', size = 'Large', weight = 'Bolder' },
{ type = 'TextBlock', text = 'No random deathmatch. Value your life. Respect staff decisions.', wrap = true },
},
actions = {
{ type = 'Action.Submit', title = 'I accept the rules', id = 'accept' },
{ type = 'Action.OpenUrl', title = 'Read all rules', url = 'https://example.com/rules' },
{ type = 'Action.Submit', title = 'Leave', id = 'leave' },
},
}
AddEventHandler('playerConnecting', function(name, setKickReason, deferrals)
deferrals.defer()
Wait(0)
deferrals.presentCard(card, function(data)
if data.submitId == 'accept' then
deferrals.done()
else
deferrals.done('You need to accept the rules to play.')
end
end)
end)Remember accepted players (for example by licence in the database) so the card only appears on their first join.
Reading inputs
local passwordCard = {
type = 'AdaptiveCard', version = '1.0',
body = {
{ type = 'TextBlock', text = 'This server is in closed testing.', wrap = true },
{ type = 'Input.Text', id = 'password', placeholder = 'Password' },
},
actions = { { type = 'Action.Submit', title = 'Join', id = 'join' } },
}
-- inside playerConnecting, after defer + Wait(0):
deferrals.presentCard(passwordCard, function(data)
if data.password == GetConvar('beta_password', '') then
deferrals.done()
else
deferrals.done('Wrong password.')
end
end)Input values arrive keyed by their id. Keep the password in a server-only convar (set, not setr). The field is not masked, so treat it as a light gate, not real security.
Chaining cards
Call presentCard again inside the callback to show the next step — language choice, then rules, then a welcome — and call done at the end. Two or three steps are plenty; players want to play.
Tips
- Test every card in the real client — not every designer feature renders the same in FiveM.
- Do not rely on colours or fancy layouts; the host app decides much of the styling.
- Keep text short; long rules belong on a website or the loading screen — see rules on the loading screen.
- Handle players who close the game mid-card: nothing to clean up, but do not leave state waiting for them.
Common questions
How do I show a card when players connect to FiveM?
Call deferrals.presentCard(cardJsonOrTable, callback) inside playerConnecting after deferrals.defer() and a one-tick wait.
How do I know which button was pressed?
Give each Action.Submit an id; it arrives in the callback data as submitId.
Where can I design Adaptive Cards?
In the Adaptive Cards Designer on adaptivecards.io; copy the JSON into your script.
Can I put a password on my FiveM server?
Yes — show a card with an Input.Text and compare the submitted value with a server-only convar.
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