> For the complete documentation index, see [llms.txt](https://docs.lostdev.store/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lostdev.store/tablet/integrating-your-resource.md).

# integrating your resource

This is the part that matters if you're building a new "app" for the tablet, either your own custom resource or a third-party one. The contract is: your resource registers an icon and listens for its own `openEvent` to open its own NUI.

{% stepper %}
{% step %}

## Register your app on resource start

In your resource's `client/main.lua` (or wherever you already open your own NUI from), guard the registration with both your own config flag and a check that `ld_tablet` is actually running:

```lua
local function registerWithTablet()
    if not Config.UI.useSharedTablet then return end
    if GetResourceState('ld_tablet') ~= 'started' then return end

    exports.ld_tablet:RegisterTabletApp({
        id = 'my_resource',                              -- unique across all apps
        label = 'My App',                                -- shown under the icon
        icon = 'fa-solid fa-flag-checkered',              -- FontAwesome class string
        color = 'linear-gradient(155deg, #2f7dfb, #1c4a97)', -- CSS background for the emblem
        resourceName = GetCurrentResourceName(),          -- optional, defaults to the caller
        openEvent = 'my_resource:client:openFromTablet',  -- local client event ld_tablet will fire
    })
end

CreateThread(function()
    Wait(1000) -- let ld_tablet finish starting if both resources start together
    registerWithTablet()
end)

-- ld_tablet might restart on its own after your resource already registered once --
-- it broadcasts this event once it's back up so you can register again.
RegisterNetEvent('ld_tablet:client:ready', registerWithTablet)
```

Add a `Config.UI.useSharedTablet` boolean to your own resource's config so server owners can opt out and keep using your resource's original standalone open command/keybind/item instead.
{% endstep %}

{% step %}

## Listen for your `openEvent` and open your own NUI

```lua
RegisterNetEvent('my_resource:client:openFromTablet', function()
    OpenMyUi(false) -- whatever function already opens your NUI + sets focus
end)
```

That's it — `ld_tablet` closes itself and fires this event; your resource takes it from there.
{% endstep %}

{% step %}

## Unregister when appropriate (optional)

`ld_tablet` already removes your app automatically when your resource stops (via `onClientResourceStop`), so this is only needed if you want to hide the icon while your resource is still running, such as for a feature-flag toggle:

```lua
exports.ld_tablet:UnregisterTabletApp('my_resource')
```

{% endstep %}

{% step %}

## Add a “Home” button so players can switch back without closing the tablet

`ld_tablet` never re-embeds your app's NUI — it hands off to it fully. To keep that handoff feeling like one continuous device instead of “tablet closes, a different app opens”, give your app's own UI a Home button that closes itself and calls back into `ld_tablet`:

```lua
RegisterNUICallback('my_resource:goHome', function(_, cb)
    closeMyUi() -- whatever already closes your own NUI + drops focus

    if Config.UI.useSharedTablet and GetResourceState('ld_tablet') == 'started' then
        pcall(function() exports.ld_tablet:OpenTablet() end)
    end

    cb({ ok = true })
end)
```

`exports.ld_tablet:OpenTablet()` reopens the tablet's home screen **already unlocked**. It skips the lock screen, since the player unlocked it once already to get here this session. This differs from the tablet's normal cold-open via item/keybind. Wrap the call in `pcall` since it's an optional integration.

On the visual side, `ld_races` and `ld_territories` both share the same `.backdrop` / `.tablet` / `.bezel` / `.screen` chrome classes `ld_tablet` itself uses: the same physical-device frame, camera dot, and screen sheen. The handoff therefore reads as “the same tablet, different app” rather than two unrelated windows. If you're building a new app, copying that chrome, or at least matching `theme.css`'s color tokens, is recommended but not required.
{% endstep %}
{% endstepper %}

## `appDef` reference

| Field          | Type   | Required | Notes                                                                        |
| -------------- | ------ | -------- | ---------------------------------------------------------------------------- |
| `id`           | string | yes      | Unique across all registered apps (re-registering the same `id` replaces it) |
| `label`        | string | yes      | Text shown under the icon                                                    |
| `icon`         | string | yes      | FontAwesome class string, e.g. `'fa-solid fa-flag-checkered'`                |
| `color`        | string | yes      | CSS `background` value for the icon emblem (gradient or solid)               |
| `resourceName` | string | no       | Defaults to the calling resource (used to auto-clean on stop)                |
| `openEvent`    | string | yes      | Local client event `ld_tablet` fires with `TriggerEvent` on click            |

## Optional integration hook

No hard dependency required. One event fires so you can hook your own systems without touching this resource's code:

* `TriggerEvent('ld_tablet:client:ready')` — fired locally once `ld_tablet` has finished starting; listen for it to (re)register your app, especially important if `ld_tablet` restarts on its own.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.lostdev.store/tablet/integrating-your-resource.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
