> For the complete documentation index, see [llms.txt](https://s1h.gitbook.io/info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://s1h.gitbook.io/info/resources/s1h_uipack/editable-files/integration.md).

# Integration

***

### QBCore Integration

You can easily route all default QBCore notifications and progressbars to **s1h\_uipack** without changing all your scripts one by one. Just replace the core functions in `qb-core` with the ones below.

***

#### 1. Client-side Notifications

**File:** `qb-core/client/functions.lua`

Replace your existing `QBCore.Functions.Notify` function (and add the state handlers at the top) with this code. This will catch all client-side notifications and send them through the UI pack.

```lua
local uipackActive = GetResourceState('s1h_uipack') == 'started'

AddEventHandler('onResourceStart', function(res)
    if res == 's1h_uipack' then uipackActive = true end
end)
AddEventHandler('onResourceStop', function(res)
    if res == 's1h_uipack' then uipackActive = false end
end)

function QBCore.Functions.Notify(text, texttype, length, icon)
    local duration   = length or 5000
    local notifyType = texttype or 'primary'

    if uipackActive then
        local mappedType = notifyType == 'primary' and 'info' or notifyType
        local messageText, titleText

        if type(text) == 'table' then
            messageText = text.text or 'Message'
            titleText   = text.caption
        else
            messageText = text or 'Message'
        end

        local ok = pcall(function()
            exports['s1h_uipack']:SendAdvancedNotify(titleText, messageText, mappedType, duration, icon)
        end)
        if ok then return end
    end

    local message = { action = 'notify', type = notifyType, length = duration }

    if type(text) == 'table' then
        message.text    = text.text    or 'Placeholder'
        message.caption = text.caption or 'Placeholder'
    else
        message.text = text or 'Placeholder'
    end

    if icon then message.icon = icon end
    SendNUIMessage(message)
end
```

***

#### 2. Server-side Notifications

**File:** `qb-core/server/player.lua`

Replace the `Player:Notify` function with this one. It directly uses the server-side export for maximum efficiency. If the UI pack is turned off for any reason, it automatically falls back to standard QBCore behavior.

```lua
function Player:Notify(text, texttype, length)
    local notifyType = texttype or 'primary'
    local duration = length or 5000

    if GetResourceState('s1h_uipack') == 'started' then
        local mappedType = notifyType == 'primary' and 'info' or notifyType
        local messageText, titleText

        if type(text) == 'table' then
            messageText = text.text or 'Message'
            titleText = text.caption
        else
            messageText = text or 'Message'
        end

        exports['s1h_uipack']:SendAdvancedNotify(self.PlayerData.source, titleText, messageText, mappedType, duration)
    else
        -- Fallback to standard QBCore trigger if the UI pack is stopped
        TriggerClientEvent('QBCore:Notify', self.PlayerData.source, text, notifyType, length)
    end
end
```

***

#### 3. Progressbar

**File:** `qb-core/client/functions.lua`

Replace your `QBCore.Functions.Progressbar` function with this. It completely swaps out the old `progressbar` dependency and pipes it directly into the `s1h_uipack` export without breaking any of your existing scripts.

```lua
function QBCore.Functions.Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
    if GetResourceState('s1h_uipack') ~= 'started' then 
        error('s1h_uipack needs to be started in order for QBCore.Functions.Progressbar to work') 
    end
    
    exports['s1h_uipack']:Progress({
        name = name:lower(),
        duration = duration,
        label = label,
        useWhileDead = useWhileDead,
        canCancel = canCancel,
        controlDisables = disableControls,
        animation = animation,
        prop = prop,
        propTwo = propTwo,
    }, function(cancelled)
        if not cancelled then
            if onFinish then
                onFinish()
            end
        else
            if onCancel then
                onCancel()
            end
        end
    end)
end
```

***

***

### qbx\_core (Qbox) Integration

You can easily route all Qbox notifications and progressbars to **s1h\_uipack** while keeping `ox_lib` as a fallback if the UI pack is stopped. Replace the core functions in `qbx_core` with the ones below.

***

#### 1. Client-side Notifications

**File:** `qbx_core/client/functions.lua`

Replace the existing `Notify` function with this. It will automatically redirect `ox_lib` style notifications to `s1h_uipack`.

```lua
function Notify(text, notifyType, duration, subTitle, notifyPosition, notifyStyle, notifyIcon, notifyIconColor)
    local title, description
    if type(text) == 'table' then
        title = text.text or 'Placeholder'
        description = text.caption or nil
    elseif subTitle then
        title = text
        description = subTitle
    else
        description = text
    end
    
    local nType = notifyType or 'info'
    if nType == 'inform' then nType = 'info' end -- Map Qbox 'inform' to 'info'

    if GetResourceState('s1h_uipack') == 'started' then
        exports['s1h_uipack']:SendAdvancedNotify(title, description, nType, duration or 5000)
        return
    end

    -- Fallback to ox_lib if s1h_uipack is not running
    local position = notifyPosition or positionConfig
    lib.notify({
        id = title,
        title = title,
        description = description,
        duration = duration,
        type = notifyType,
        position = position,
        style = notifyStyle,
        icon = notifyIcon,
        iconColor = notifyIconColor
    })
end
```

***

#### 2. Server-side Notifications

**File:** `qbx_core/server/functions.lua`

Replace the existing `Notify` function. This directly uses the `s1h_uipack` server export for efficiency, but falls back to `ox_lib:notify` if the UI pack is turned off.

```lua
function Notify(source, text, notifyType, duration, subTitle, notifyPosition, notifyStyle, notifyIcon, notifyIconColor)
    local title, description
    if type(text) == 'table' then
        title = text.text or 'Placeholder'
        description = text.caption or nil
    elseif subTitle then
        title = text
        description = subTitle
    else
        description = text
    end
    
    local nType = notifyType or 'info'
    if nType == 'inform' then nType = 'info' end -- Map Qbox 'inform' to 'info'

    if GetResourceState('s1h_uipack') == 'started' then
        exports['s1h_uipack']:SendAdvancedNotify(source, title, description, nType, duration or 5000)
        return
    end

    -- Fallback to ox_lib if s1h_uipack is not running
    local position = notifyPosition or positionConfig
    TriggerClientEvent('ox_lib:notify', source, {
        id = title,
        title = title,
        description = description,
        duration = duration,
        type = notifyType,
        position = position,
        style = notifyStyle,
        icon = notifyIcon,
        iconColor = notifyIconColor
    })
end
```

***

#### 3. Progressbar (Bridge)

**File:** `qbx_core/bridge/qb/client/functions.lua`

Replace the `functions.Progressbar` bridge function. It will trigger `s1h_uipack`'s progress bar instead of `lib.progressBar`.

```lua
function functions.Progressbar(_, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
    if GetResourceState('s1h_uipack') == 'started' then
        exports['s1h_uipack']:Progress({
            name = "qbx_progress",
            duration = duration,
            label = label,
            useWhileDead = useWhileDead,
            canCancel = canCancel,
            controlDisables = disableControls,
            animation = animation,
            prop = prop,
            propTwo = propTwo,
        }, function(cancelled)
            if not cancelled then
                if onFinish then onFinish() end
            else
                if onCancel then onCancel() end
            end
        end)
        return
    end

    -- Fallback to original ox_lib logic if s1h_uipack is not running
    local props
    if prop?.model then
        local propData = {
            model = prop.model,
            bone = prop.bone,
            pos = prop.coords,
            rot = prop.rotation,
        }

        if propTwo?.model then
            props = {
                propData,
                {
                    model = propTwo.model,
                    bone = propTwo.bone,
                    pos = propTwo.coords,
                    rot = propTwo.rotation,
                },
            }
        else
            props = propData
        end
    end

    if lib.progressBar({
        duration = duration,
        label = label,
        useWhileDead = useWhileDead,
        canCancel = canCancel,
        disable = {
            move = disableControls?.disableMovement,
            car = disableControls?.disableCarMovement,
            combat = disableControls?.disableCombat,
            mouse = disableControls?.disableMouse,
        },
        anim = {
            dict = animation?.animDict,
            clip = animation?.anim,
            flag = animation?.flags
        },
        prop = props,
    }) then
        if onFinish then
            onFinish()
        end
    else
        if onCancel then
            onCancel()
        end
    end
end
```

***

***

### ESX Framework Integration

You can easily route ESX notifications and progressbars to **s1h\_uipack**. These snippets preserve ESX's native return logic (like the progress bar returning a boolean after completion).

***

#### 1. Client-side Notifications

**File:** `es_extended/client/functions.lua`

Replace your existing `ESX.ShowNotification` function.

```lua
function ESX.ShowNotification(message, notifyType, length, title, position)
    if GetResourceState('s1h_uipack') == 'started' then
        exports['s1h_uipack']:SendAdvancedNotify(title, message, notifyType or "info", length or 5000)
        return
    end

    -- Fallback to default ESX notify if s1h_uipack is missing
    return IsResourceFound('esx_notify') and exports['esx_notify']:Notify(notifyType or "info", length or 5000, message, title, position)
end
```

***

#### 2. Server-side Notifications

**File:** `es_extended/server/classes/player.lua` (Inside the `xPlayer` functions)

Update the `xPlayer.showNotification` function to use the UI pack's server export for better performance.

```lua
function xPlayer.showNotification(message, notifyType, length)
    if GetResourceState('s1h_uipack') == 'started' then
        exports['s1h_uipack']:SendAdvancedNotify(self.source, nil, message, notifyType or "info", length or 5000)
    else
        -- Fallback to default ESX trigger
        TriggerClientEvent('esx:showNotification', self.source, message, notifyType, length)
    end
end
```

***

#### 3. Progressbar

**File:** `es_extended/client/functions.lua`

Replace your existing `ESX.Progressbar` function.

**Note:** This integration is highly advanced. It supports **both** older ESX scripts that pass `onFinish`/`onCancel` inside the options table, **and** modern ESX scripts that expect the progress bar to halt the thread and return a boolean (`true`/`false`).

```lua
function ESX.Progressbar(message, length, options)
    if GetResourceState('s1h_uipack') == 'started' then
        options = options or {}
        local p = promise.new()
        
        exports['s1h_uipack']:Progress({
            name = "esx_progress",
            duration = length or 5000,
            label = message or "Processing...",
            useWhileDead = options.useWhileDead or false,
            canCancel = options.canCancel ~= false,
            controlDisables = options.disableControls or {
                disableMovement = false,
                disableCarMovement = false,
                disableMouse = false,
                disableCombat = true,
            },
            animation = options.animation or options.anim,
            prop = options.prop,
            propTwo = options.propTwo
        }, function(cancelled)
            -- Support for older callback-style ESX scripts
            if cancelled then
                if options.onCancel then options.onCancel() end
            else
                if options.onFinish then options.onFinish() end
            end
            
            -- Resolve promise for modern synchronous ESX scripts
            p:resolve(not cancelled)
        end)
        
        -- Await halts the thread until completion and returns the boolean
        return Citizen.Await(p)
    end
    
    -- Fallback to default ESX progressbar if s1h_uipack is missing
    return IsResourceFound('esx_progressbar') and exports['esx_progressbar']:Progressbar(message, length, options)
end
```
