How to create a FiveM server website

A complete walkthrough, from an empty folder to a deployed site with your server's live player count on it, using the RPWebsite template.

Last updated

Most FiveM communities start with a Discord invite and a Tebex page, and put off the website until someone asks where the rules are. This guide is the short version of building that website: configure the template, point it at your server, write your own pages, deploy. It takes about an hour the first time, and none of it requires you to write React.

The steps below use RPWebsite, which is the template this site sells. Where a step is really about FiveM rather than about this template, it is marked as such, so the guide stays useful even if you build your site some other way.

What you need before you start

Four things, and only the first two are strictly required.

  • Node.js 20 or newer, and pnpm. The template is a Next.js app. node --version should print v20 or higher.
  • A domain. It does not have to be pointed anywhere yet, but the site needs to know its own address at build time, so decide on it now.
  • Your cfx.re join code, if you want the live player count and a working join button. It is the six-character code in cfx.re/join/xxxxxx, and you can also read it from the in-game F8 console.
  • A place to deploy. Vercel is the path of least resistance and has a free tier that fits a community site. Anything that runs next start also works.

You do not need a database, a CMS, a login system or a backend. The site reads your server's status from a public API at request time, and everything else from files in the repository.

Install it and get it running locally

Unpack the template, then from inside the folder:

pnpm install
cp .env.example .env.local
pnpm dev

Open http://localhost:3000. You are looking at a complete site with placeholder content: a homepage, rules, an FAQ, news, and legal pages, in four languages.

Leave pnpm dev running in that terminal for the rest of this guide. It reloads as you edit, so every change below is visible within a second or two.

Point the site at your FiveM server

Open .env.local, the file you just copied. Two values matter now.

NEXT_PUBLIC_SITE_URL=https://your-domain.example
NEXT_PUBLIC_CFX_JOIN_CODE=abc123

NEXT_PUBLIC_SITE_URL is the public address of the finished site. Every absolute URL is built from it: the canonical link, the hreflang tags, the sitemap, the social preview card. It is the one value pnpm build refuses to go without, which is deliberate. A site that tells Google it lives on localhost is worse than a site that fails to build.

NEXT_PUBLIC_CFX_JOIN_CODE powers both the live status section and the join button. Save the file, restart pnpm dev so it picks up the new variables, and the status section should show your real player count.

If the count says your server is offline while the server is plainly running, skip ahead to the last section.

Set your server's identity

Open src/config/site.ts. This is where the template is configured, and it is a plain TypeScript object with comments on every field. The ones worth changing on day one:

  • name is your server's name, which the browser tab, the header and the social card all read.
  • platform is fivem or ragemp. It decides which status adapter runs and what the join button does.
  • theme is noir, crimson or azure. An unknown value fails the build on purpose, because a typo in a hosting dashboard is otherwise invisible until someone screenshots the wrong colours.
  • features holds the switches for whole pages. Turn off what you are not going to maintain. An empty news page is worse than no news page.
  • legal holds your operator details. Running a community site commercially usually obliges you to publish them, and leaving these empty prints nothing at all.

Write your own pages

Two directories hold everything a visitor reads.

messages/en.json is the interface copy: headings, button labels, section intros. There is one file per language. A key that exists in one language and not another is a build failure rather than a silent fallback, so the four files stay in step by construction.

content/en/ holds the long-form pages as Markdown: your rules, your FAQ, your news posts, your imprint and privacy pages. Adding a file publishes a page. There is no route to register and no config entry to remember, because placement in the navigation is declared by the file's own frontmatter.

Start with content/en/rules.mdx. It is the page new players actually read, and the placeholder text in it is not your ruleset.

Deploy it

Before deploying, run the check that CI runs:

pnpm check

That builds, typechecks and lints, in that order, because next build generates the route types that TypeScript then checks the pages against. If it passes, the site is deployable.

On Vercel: import the repository, set the same variables you put in .env.local in the project's environment settings, and deploy. There is no build step beyond next build and no service to provision.

On a VPS, Coolify, Docker or Railway: anything that runs next start works identically. Set the environment variables in your host's dashboard rather than committing .env.local.

One thing to know before you go looking for it: static export is not supported as shipped. A proxy runs on every request to resolve the visitor's language, and a static export has no request phase. The template's README documents the four-step recipe for going static anyway, and what you give up for it: the generated social preview card, the RAGE:MP lookup helper, and image optimization.

When the player count says offline

This is the most common support question, and it usually has one of three causes.

The join code is wrong or missing. Check it against cfx.re/join/xxxxxx for your server. The code is case-sensitive.

Your server refuses the request. FiveM's sv_requestParanoia setting, at 2 or higher, makes the built-in JSON endpoints refuse everyone, including your own website. The fix is not to lower it. Set up the status resource that ships in integrations/fivem-status/ on your server instead, and point the site at it:

CUSTOM_STATUS_URL=http://your-server:30120/fivem-status/?token=your-secret

That path is also how you get the daily-peak figure, which the Cfx API cannot report at all.

You are trying to use txAdmin. It ships no public REST API, and its one environment-gated endpoint reports host metrics behind the admin port rather than players. The resource above is the supported route.

If the count is right locally but wrong in production, check that the environment variable is actually set in your host's dashboard. .env.local is not deployed, by design.

from $99

One-time · full source code

Get it now