> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nonefivem.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Client Exports

> Client-side exports for reading feature flags

Clients read the shared flags out of `GlobalState`, which the server publishes and the game replicates. There is no round trip and no request — the value is already on the machine — so **client reads are synchronous and safe inside a tick**.

<Note>
  Only `shared` flags are published. Reading a `server` flag from a client is
  exactly like reading one that does not exist: it returns the fallback.
</Note>

A joining player holds the values before your resource runs a line, because the state bag arrives with the connection rather than being requested.

## Exports

<Accordion title="IsFlagEnabled">
  Checks whether a boolean flag is on.

  ```lua theme={null}
  if exports.nocloud:IsFlagEnabled('new-hud') then
      -- ...
  end

  -- With an explicit fallback
  local maintenance = exports.nocloud:IsFlagEnabled('maintenance-mode', true)
  ```

  **Parameters**

  * key: `string` — The flag's key
  * fallback: `boolean` — Returned when the flag is not a readable boolean flag (optional, `false` by default)

  **Returns**

  * enabled: `boolean` — Whether the flag is on

  A missing flag, one holding a non-boolean value, or one the server does not share with clients all return the fallback.
</Accordion>

<Accordion title="GetFlagValue">
  Reads a flag's value, whatever its type.

  ```lua theme={null}
  local motd = exports.nocloud:GetFlagValue('motd', 'Welcome')
  local maxPlayers = exports.nocloud:GetFlagValue('max-players', 32)
  ```

  **Parameters**

  * key: `string` — The flag's key
  * fallback: `any` — Returned when the flag is missing, or before the server has published any (optional)

  **Returns**

  * value: `any` — The flag's value, or the fallback
</Accordion>

<Accordion title="GetFlags">
  Reads every flag this client holds, keyed by flag key.

  ```lua theme={null}
  local flags = exports.nocloud:GetFlags()

  for key, value in pairs(flags) do
      print(key, json.encode(value))
  end
  ```

  **Returns**

  * values: `table` — The flag values, keyed by flag key. Empty before the server has published any.
</Accordion>

<Accordion title="AreFlagsReady">
  Whether the server has published any values yet.

  ```lua theme={null}
  if exports.nocloud:AreFlagsReady() then
      -- ...
  end
  ```

  **Returns**

  * ready: `boolean`

  Reads before this is true fall back, so this is what to check when you would rather show nothing than show a fallback.
</Accordion>

## Reading the state bag directly

The exports are a thin wrapper that handles the empty case. Nothing stops you reading the bag yourself:

```lua theme={null}
local flags = GlobalState.nocloud_flags

if flags and flags['new-hud'] then
    -- ...
end
```

<Warning>
  Reading the bag directly skips the subscription signal. The server stops
  refreshing the flags when no client says it is reading them, so a resource that
  *only* reads `GlobalState` may sit on values that stop being refreshed. Either
  go through the exports, or set `flags.polling.enabled` to `true` in the
  [configuration](/cloud/sdks/cfx/configuration#feature-flags).
</Warning>

The key is `flags.global_state_key` from your configuration — `nocloud_flags` by default.

## Reacting to changes

There is no client event. Watch the state bag directly:

```lua theme={null}
AddStateBagChangeHandler('nocloud_flags', 'global', function(_, _, values)
    -- values is every flag this client holds
    print('flags changed:', json.encode(values))
end)
```

The bag is only rewritten when what players can see has actually changed, so a server-only flag being edited never costs your handler a wake-up.

## What leaves the client

Almost nothing. Reading tells the server that this client reads flags, so it keeps them current, and five minutes without a read tells it you have stopped.

<Note>
  Those two signals carry **no data** and only fire at the edges — not per read.
  Every read is a local lookup and nothing more, so reading a flag inside a tick
  sends nothing over the network.
</Note>

A client announcing itself is rate limited to 5 times per minute per player, so the signal cannot be used to spam the server.

## Lua Library

For a cleaner API, include the client Lua library in your `fxmanifest.lua`:

```lua theme={null}
client_script '@nocloud/lib/client.lua'
```

**Usage**

```lua theme={null}
-- Boolean flag
if Cloud.flags:is_enabled('new-hud') then
    -- ...
end

-- Any value
local motd = Cloud.flags:get_value('motd', 'Welcome')

-- Every flag this client holds
local all = Cloud.flags:get_all()

-- Whether the server has published any values yet
local ready = Cloud.flags:is_ready()
```

The library ships full LuaLS annotations, so `Cloud.flags` autocompletes with parameter and return types in any editor with the Lua Language Server.
