# Custom apps

If you're looking to create your own custom app for the WLabs tablet you're in the right place, this script is a perfect template to get started. When creating an app treat the tablet as a host that your app loads inside of.

There are two supported ways to add a custom app:

1. `Config.CustomApps` in `config.lua`
2. Registration with `exports('RegisterApp', app)` from another resource

## How this works

The tablet loads built-in apps, custom apps from `Config.CustomApps`, and apps registered at runtime.

## Static app registration (`Config.CustomApps`)

Use `Config.CustomApps` to register an app from `config.lua`.

Example:

```lua
Config.CustomApps = {
    wlabs_towing = {
        label = 'LS Tow',
        description = 'Use towing tools and job features.',
        ui = 'https://cfx-nui-wlabs-towing/html/tablet.html',
        icon = 'https://cfx-nui-wlabs-tablet/html/build/icons/tow.png',
        resource = 'wlabs-towing',
        fullscreen = true,
    }
}
```

Key fields:

* `key` — the custom app identifier (the table key in `Config.CustomApps`)
* `label` — app name shown in the tablet catalog
* `description` — optional app description
* `ui` — external NUI page URL, usually `https://cfx-nui-<resource>/html/<page>.html`
* `icon` — app icon URL
* `resource` — optional resource name that must be started for the app to appear
* `fullscreen` — `true` if the external page should occupy the full tablet workspace

If `resource` is set and not started, the app is hidden until that resource becomes available.

## Runtime app registration (`RegisterApp`)

A separate resource can register an app with the tablet export, this is the best method to use if you want to create a fully independent app for the tablet.

Example:

```lua
Citizen.CreateThread(function()
    while GetResourceState('wlabs-tablet') ~= 'started' do
        Wait(100)
    end

    exports['wlabs-tablet']:RegisterApp({
        key = 'mytabletapp', --make this unique to your app, if another app you're using has this exact key it will override and cause conflicts.
        label = 'My App',
        description = 'A custom tablet app built in another resource.',
        ui = 'https://cfx-nui-my-resource/html/tablet.html',
        icon = 'https://cfx-nui-my-resource/html/icons/myapp.png',
        resource = GetCurrentResourceName(),
        fullscreen = true,
    })
end)
```

## What you need in order to create an app for the WLabs Tablet

* your own resource folder
* your own NUI page(s) under that resource
* an icon and app metadata

## Open-source test app example

I've created a template app that's completely open source to help you build your own custom app:

```
A complete starter resource is available on Tebex:
https://wlabs.tebex.io
```

This app is small but functions perfect and is a great starting point for new apps:

* `fxmanifest.lua` for the resource setup
* `client/main.lua` for `exports['wlabs-tablet']:RegisterApp(...)`
* `html/nui.html` for the hidden top-level FiveM NUI page
* `html/tablet.html` for the tablet page
* `html/style.css` for a tablet-friendly layout
* `html/app.js` for a simple NUI callback
* `html/icons/hello.svg` for the app icon

If you want to see this template in action, add this to `server.cfg` after the tablet:

```cfg
ensure wlabs-tablet
ensure wlabs-tablet-example-app
```

Then open the tablet, download **Test App** from the app store, and open it.

If you are developing an app for my tablet, feel free to join the discord and talk about it! I would love to see any projects involving my tablet, and am happy to help in any way I can!

Discord: <https://discord.gg/fSeqDaprxs>


---

# Agent Instructions: 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:

```
GET https://w-labs.gitbook.io/w-labs-docs/scripts/wlabs-tablet/custom-apps.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
