Comment créer une NUI FiveM avec React ? Guide 2025 devient une question incontournable pour tout développeur cherchant à moderniser l’interface de son serveur roleplay. React, avec son architecture par composants et sa réactivité, s’impose comme le framework JavaScript de prédilection pour concevoir des interfaces utilisateur fluides, performantes et maintenables. Dans ce guide complet, nous explorons l’ensemble du processus de création d’une NUI FiveM avec React, depuis la configuration initiale jusqu’au déploiement sur votre serveur, en passant par les bonnes pratiques de communication entre le client Lua et votre interface React.
Qu’est-ce qu’une NUI FiveM et pourquoi choisir React ?
La NUI (New User Interface) constitue le système d’interface graphique de FiveM, reposant sur le moteur CEF (Chromium Embedded Framework). Contrairement aux interfaces natives de GTA V, la NUI permet de créer des interfaces web complètes en HTML, CSS et JavaScript, offrant une liberté créative quasi illimitée aux développeurs de scripts.
Les avantages de React pour vos interfaces FiveM
React révolutionne le développement de NUI FiveM grâce à plusieurs atouts décisifs. Le système de composants réutilisables accélère considérablement le développement et facilite la maintenance à long terme. Le Virtual DOM optimise les performances en minimisant les manipulations du DOM réel, crucial lorsque votre interface affiche des données dynamiques mises à jour fréquemment.
L’écosystème React propose des milliers de bibliothèques prêtes à l’emploi : animations avec Framer Motion, gestion d’état avec Zustand ou Redux, composants UI avec Material-UI ou Chakra UI. Cette richesse réduit drastiquement le temps de développement tout en garantissant un code professionnel.
Prérequis techniques avant de commencer
Avant de créer votre première NUI FiveM avec React, assurez-vous de disposer des outils suivants :
- Node.js (version 16 ou supérieure) et npm ou yarn comme gestionnaire de paquets
- Un éditeur de code moderne comme Visual Studio Code avec les extensions ESLint et Prettier
- Des connaissances de base en JavaScript ES6+, HTML et CSS
- Une compréhension fondamentale du scripting Lua FiveM et de l’API client
- Un serveur de développement FiveM fonctionnel pour tester vos créations
Si vous recherchez un hébergement performant pour développer et déployer vos projets, Location FiveM propose des serveurs optimisés spécialement conçus pour les développeurs exigeants.
Configuration initiale : créer votre projet NUI React
La mise en place d’un projet NUI FiveM avec React nécessite une structure spécifique et une configuration adaptée aux contraintes de l’environnement CEF. Suivez ces étapes méthodiquement pour partir sur des bases solides.
Initialisation du projet avec Vite
Vite s’impose aujourd’hui comme l’outil de build le plus rapide et moderne pour React. Contrairement à Create React App devenu obsolète en 2025, Vite offre un Hot Module Replacement instantané et des temps de compilation réduits de 90%. Créez votre projet avec cette commande :
npm create vite@latest ma-nui-fivem -- --template react
cd ma-nui-fivem
npm install
Structure des dossiers recommandée
Une organisation claire du code facilite grandement la maintenance. Voici la structure optimale pour un projet NUI FiveM React professionnel :
ma-nui-fivem/
├── client/
│ └── client.lua
├── server/
│ └── server.lua
├── fxmanifest.lua
└── nui/
├── public/
├── src/
│ ├── components/
│ ├── hooks/
│ ├── utils/
│ ├── App.jsx
│ └── main.jsx
├── package.json
└── vite.config.js
Configuration du fichier fxmanifest.lua
Le manifest FiveM doit déclarer correctement vos fichiers NUI compilés. Voici une configuration type fonctionnelle :
fx_version 'cerulean'
game 'gta5'
author 'Votre Pseudo'
description 'NUI React moderne'
version '1.0.0'
client_scripts {
'client/client.lua'
}
server_scripts {
'server/server.lua'
}
ui_page 'nui/dist/index.html'
files {
'nui/dist/**/*'
}
Configuration de Vite pour FiveM
Le fichier vite.config.js requiert des ajustements spécifiques pour garantir la compatibilité avec l’environnement CEF de FiveM. La configuration suivante résout les problèmes courants de chemins relatifs :
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
base: './',
build: {
outDir: 'dist',
assetsDir: 'assets',
emptyOutDir: true
}
})
Le paramètre base: ‘./’ garantit que tous les chemins d’assets seront relatifs, évitant ainsi les erreurs 404 fréquentes lors du chargement dans CEF.
Communication entre Lua et React : le système de messages
La communication bidirectionnelle entre votre script client Lua et votre interface React constitue le cœur fonctionnel de toute NUI FiveM. Maîtriser ce mécanisme permet de créer des interfaces véritablement interactives et réactives aux événements du jeu.
Envoyer des données de Lua vers React
Du côté client Lua, utilisez la fonction SendNUIMessage pour transmettre des données structurées à votre interface. Chaque message doit contenir un type identifiant l’action et les données associées :
-- client/client.lua
RegisterCommand('openmenu', function()
SetNuiFocus(true, true)
SendNUIMessage({
type = 'openMenu',
data = {
playerName = GetPlayerName(PlayerId()),
money = 5000,
items = {'pain', 'eau', 'téléphone'}
}
})
end)
Réceptionner les messages dans React avec useEffect
React écoute les messages NUI via l’événement message de l’objet window. Créez un hook personnalisé pour gérer élégamment cette communication :
// src/hooks/useNuiEvent.js
import { useEffect } from 'react'
export const useNuiEvent = (type, handler) => {
useEffect(() => {
const eventListener = (event) => {
if (event.data.type === type) {
handler(event.data.data)
}
}
window.addEventListener('message', eventListener)
return () => window.removeEventListener('message', eventListener)
}, [type, handler])
}
Utilisez ensuite ce hook dans vos composants React pour réagir aux événements FiveM :
// src/App.jsx
import { useState } from 'react'
import { useNuiEvent } from './hooks/useNuiEvent'
function App() {
const [visible, setVisible] = useState(false)
const [playerData, setPlayerData] = useState(null)
useNuiEvent('openMenu', (data) => {
setVisible(true)
setPlayerData(data)
})
if (!visible) return null
return (
<div className="menu-container">
<h2>Bienvenue {playerData?.playerName}</h2>
<p>Argent : {playerData?.money}$</p>
</div>
)
}
Communiquer de React vers Lua avec fetchNui
Pour envoyer des données depuis votre interface React vers le client Lua, utilisez l’API fetch avec des callbacks NUI. Créez d’abord une fonction utilitaire réutilisable :
// src/utils/fetchNui.js
export const fetchNui = async (eventName, data = {}) => {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=UTF-8'
},
body: JSON.stringify(data)
}
try {
const response = await fetch(`https://${GetParentResourceName()}/${eventName}`, options)
return await response.json()
} catch (error) {
console.error('Erreur fetchNui:', error)
}
}
Dans votre composant React, appelez cette fonction lors d’actions utilisateur :
import { fetchNui } from './utils/fetchNui'
function MenuButton() {
const handleBuyItem = async () => {
const result = await fetchNui('buyItem', {
itemName: 'pain',
quantity: 2
})
if (result.success) {
console.log('Achat réussi')
}
}
return <button onClick={handleBuyItem}>Acheter</button>
}
Côté Lua, enregistrez les callbacks correspondants :
-- client/client.lua
RegisterNUICallback('buyItem', function(data, cb)
local itemName = data.itemName
local quantity = data.quantity
-- Logique d'achat
TriggerServerEvent('shop:buyItem', itemName, quantity)
cb({ success = true })
end)
Gestion de l’état et performance
Pour les NUI complexes gérant de nombreuses données, intégrez Zustand, un gestionnaire d’état léger et performant parfaitement adapté à FiveM :
npm install zustand
// src/store/useStore.js
import create from 'zustand'
export const useStore = create((set) => ({
isVisible: false,
playerData: null,
setVisible: (visible) => set({ isVisible: visible }),
setPlayerData: (data) => set({ playerData: data })
}))
Cette approche centralise l’état de votre application et facilite le partage de données entre composants sans prop drilling excessif.
Build, déploiement et optimisation de votre NUI React
Une fois votre interface développée et testée, l’étape de build et d’optimisation garantit des performances optimales sur les serveurs de production. FiveM impose des contraintes spécifiques qu’il convient de respecter scrupuleusement.
Compilation pour la production
Lancez la commande de build depuis le dossier nui de votre ressource :
cd nui
npm run build
Vite génère un dossier dist contenant vos fichiers HTML, CSS et JavaScript optimisés, minifiés et prêts pour la production. Vérifiez que le fichier index.html contient bien des chemins relatifs pour tous les assets.
Optimisations des performances CEF
Le moteur CEF de FiveM présente des limitations par rapport à un navigateur moderne. Appliquez ces optimisations pour garantir fluidité et réactivité :
- Lazy loading des composants : utilisez React.lazy() pour charger les composants volumineux uniquement quand nécessaire
- Limitation des re-renders : employez React.memo() et useMemo() pour éviter les calculs inutiles
- Debouncing des événements : pour les inputs de recherche ou filtres, limitez la fréquence de mise à jour
- Optimisation des images : convertissez vos assets en WebP, compressez-les et utilisez des sprites CSS pour les icônes
- Code splitting : divisez votre bundle JavaScript en plusieurs fichiers pour réduire le temps de chargement initial
Gestion du focus et du curseur
Contrôlez précisément l’état du focus NUI pour éviter les conflits avec les contrôles du jeu. Créez une fonction utilitaire dédiée :
-- client/client.lua
function ToggleNUI(state)
SetNuiFocus(state, state)
SendNUIMessage({
type = 'setVisible',
data = state
})
end
-- Fermeture avec Échap
RegisterNUICallback('closeNui', function(data, cb)
ToggleNUI(false)
cb('ok')
end)
Dans React, gérez la touche Échap proprement :
useEffect(() => {
const handleKeyDown = (e) => {
if (e.key === 'Escape') {
fetchNui('closeNui')
setVisible(false)
}
}
window.addEventListener('keydown', handleKeyDown)
return () => window.removeEventListener('keydown', handleKeyDown)
}, [])
Débogage et tests en environnement navigateur
Développer directement dans FiveM ralentit considérablement le workflow. Ajoutez une détection d’environnement pour tester votre NUI dans un navigateur classique :
// src/utils/isDevelopment.js
export const isDevelopment = !window.invokeNative
// Usage dans fetchNui
export const fetchNui = async (eventName, data = {}) => {
if (isDevelopment) {
console.log('Mode dev - fetchNui:', eventName, data)
return { success: true } // Mock response
}
// Code production...
}
Lancez votre serveur de développement Vite avec npm run dev et testez votre interface dans Chrome avec les DevTools pour identifier rapidement les problèmes CSS ou JavaScript.
Tableau récapitulatif des commandes essentielles
| Commande | Action |
npm run dev |
Lance le serveur de développement avec HMR |
npm run build |
Compile pour la production dans dist/ |
npm run preview |
Prévisualise le build de production localement |
ensure nom-ressource |
Recharge la ressource dans la console FiveM |
Ressources externes pour approfondir
La documentation officielle FiveM NUI Development constitue une référence incontournable pour comprendre les spécificités techniques du système CEF et résoudre les problèmes avancés.
Pour héberger vos créations sur une infrastructure professionnelle, découvrez les offres adaptées aux développeurs sur Location FiveM, avec support technique réactif et performances garanties.
Bonnes pratiques et erreurs courantes à éviter
Après avoir accompagné des dizaines de développeurs dans la création de NUI FiveM avec React, certaines erreurs reviennent systématiquement. Voici comment les anticiper et les résoudre.
Erreur 1 : oubli du base path dans vite.config.js
Sans le paramètre base: './', vos assets seront recherchés à la racine du protocole nui://, provoquant des erreurs 404. Tous les chemins doivent être relatifs au fichier index.html.
Erreur 2 : ne jamais appeler cb() dans un RegisterNUICallback
Chaque callback NUI côté Lua DOIT impérativement appeler la fonction cb(), même sans données de retour. Oublier cet appel bloque toutes les requêtes fetch ultérieures depuis React, générant des timeouts mystérieux difficiles à diagnostiquer.
Erreur 3 : fuites mémoire avec les event listeners
Oublier de nettoyer les event listeners dans le return de useEffect provoque des fuites mémoire et des comportements erratiques. Utilisez systématiquement la fonction de cleanup pour retirer les écouteurs.
Erreur 4 : utilisation excessive de re-renders
Mettre à jour l’état React trop fréquemment (par exemple à chaque frame du jeu) dégrade catastrophiquement les performances CEF. Implémentez du throttling ou du debouncing pour les mises à jour haute fréquence.
Checklist de validation avant mise en production
- Tous les callbacks Lua appellent
cb() - Les event listeners sont correctement nettoyés
- Le focus NUI se désactive proprement à la fermeture
- Aucune erreur dans la console F8 de FiveM
- Les performances restent fluides avec 128 joueurs connectés
- Le build de production ne contient aucun console.log superflu
- Les chemins d’assets sont relatifs, pas absolus
Créer une NUI FiveM avec React en 2025 offre des possibilités créatives infinies tout en exigeant rigueur et respect des contraintes techniques spécifiques à l’environnement CEF. En suivant méthodiquement ce guide, vous disposez désormais de toutes les clés pour développer des interfaces modernes, performantes et maintenables qui enrichiront l’expérience de vos joueurs. L’écosystème React évolue rapidement : restez à l’affût des nouvelles bibliothèques et patterns pour continuer à progresser dans votre maîtrise du développement NUI.
FAQ
Comment déboguer une NUI React qui ne s’affiche pas dans FiveM ?
Ouvrez la console F8 de FiveM et cherchez les erreurs. Vérifiez que le paramètre base: './' est bien configuré dans vite.config.js, que le fichier fxmanifest.lua déclare correctement ui_page 'nui/dist/index.html' et que les fichiers files { 'nui/dist/**/*' } sont bien présents. Utilisez également les DevTools CEF accessibles via la commande resmon dans F8, puis clic droit sur votre ressource et “Open DevTools” pour voir les erreurs JavaScript et réseau.
Puis-je utiliser TypeScript au lieu de JavaScript pour ma NUI React FiveM ?
Absolument, TypeScript est même recommandé pour les projets complexes. Créez votre projet avec npm create vite@latest ma-nui -- --template react-ts. TypeScript apporte l’autocomplétion, la détection d’erreurs à la compilation et facilite grandement la maintenance. Créez des types pour vos messages NUI et vos réponses de callbacks pour sécuriser toute la chaîne de communication entre Lua et React.
Comment gérer plusieurs NUI React dans une même ressource FiveM ?
Créez plusieurs projets React dans des sous-dossiers distincts (nui-inventory/, nui-menu/, etc.), chacun avec son propre build. Dans le fxmanifest.lua, déclarez plusieurs ui_page n’est pas possible, mais vous pouvez charger dynamiquement différentes pages HTML via SendNUIMessage avec un paramètre d’URL ou mieux, créer une Single Page Application avec React Router qui gère plusieurs vues au sein d’une seule NUI, optimisant ainsi les performances et simplifiant la gestion de l’état partagé.
