Skip to main content
The NUI page runs in the player’s game. Injected scripts and executors can post anything to its callbacks. ug-lib treats every page answer as untrusted input.

What ug-lib checks

  • Answers match a request. The page knows a layer by an id. ug-lib accepts one answer per open layer, from the id it created. Unknown and late answers are dropped.
  • Answers are built from Lua data. A menu or radial answers an index or a path. Lua maps it to its own item, so args, callbacks and ids never reach the page or come back from it.
  • Values follow their fields. A dialog answer is checked against each field: type, required, min, max, step, maxLength, options and dates. Strings lose control characters. A disabled field keeps its default.
  • Timing is checked. A skill check hit only counts when the needle could be in the area at the time the page reports.
  • Payloads are rebuilt. Every payload is rebuilt from known fields, on your side and again in ug-lib, because any resource can call its exports.
  • No HTML. The page renders text, never HTML. Formatted text uses a small markup: **bold**, *italic*, ~success~color~reset~. Images MUST be nui:// or https://.
  • Rate limits. Non-final page events are limited to 20 per layer per second.
A failed check resolves the call as Cancelled. It never raises in your code.

What stays your job

ug-lib protects the UI, not your game logic. A player can still answer a dialog with any valid value. Your server MUST check every intent again: prices, amounts, distances and permissions. With UgCore, use schemas, rate limits and Guard.IsNear. See Security.