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

# qb-inventory swap hook

> Add the RegisterOnSwapItems export a product needs to see items move between inventories on qb-inventory.

Some products need to know when a player moves an item from one inventory to another, and to be able
to refuse the move: a shop that must not be emptied into a stash, a container that only accepts
certain items. Every other supported inventory offers a way to watch this. Stock `qb-inventory` does
not, so a product that needs it reports this and stops:

```text theme={null}
[qb-inventory] onSwapItems needs the RegisterOnSwapItems export, which stock qb-inventory does not have. Add it by following https://docs.elementlabs.net/sdk/qb-inventory-swap-hook.
```

This page adds that export: about fifteen lines in two of `qb-inventory`'s files. Nothing else on your
server changes.

> [!NOTE]
>
> Only products that watch items moving need this. If no product prints the line above, there is
> nothing to do.

## Before you start

* `qb-inventory` from `qbcore-framework/qb-inventory`, running on your server. In a fork the function
  names are the same, but the surrounding lines may differ.
* A copy of `server/functions.lua` and `server/main.lua` from `qb-inventory`, to restore if needed.

## Steps

**1. Add the export**

At the end of `qb-inventory/server/functions.lua`, add:

```lua theme={null}
local swapHooks = {}

--- Registers a handler called before an item moves between two inventories.
--- Returning false from any handler refuses the move.
function RegisterOnSwapItems(handler)
    swapHooks[#swapHooks + 1] = handler
end

exports('RegisterOnSwapItems', RegisterOnSwapItems)

--- Runs every handler. Returns false as soon as one of them refuses.
function RunSwapHooks(payload)
    for _, handler in ipairs(swapHooks) do
        if handler(payload) == false then
            return false
        end
    end
    return true
end
```

**2. Call it before an item moves**

In `qb-inventory/server/main.lua`, find the handler that starts like this:

```lua theme={null}
RegisterNetEvent('qb-inventory:server:SetInventoryData', function(fromInventory, toInventory, fromSlot, toSlot, fromAmount, toAmount)
```

Inside it, after the two lines that call `getItem` and **before** anything is added or removed,
insert:

```lua theme={null}
    local allowed = RunSwapHooks({
        source = src,
        action = toItem and 'swap' or 'move',
        fromInventory = fromInventory,
        toInventory = toInventory,
        fromType = nil,
        toType = nil,
        fromSlot = fromItem or fromSlot,
        toSlot = toItem or toSlot,
        count = toAmount or fromAmount,
    })

    if not allowed then return end
```

Returning early is what refuses the move: the item never leaves its slot, and the player's
inventory redraws unchanged.

**3. Restart both**

```text theme={null}
restart qb-inventory
restart element_3d_pausemenu
```

Use the name of the product that printed the line.

## Check that it worked

The product no longer prints the line above when it starts. Move an item into an inventory the
product watches: if the product refuses that move, the item stays where it was.

## What a handler receives

| Field | Meaning |
| - | - |
| `source` | The player who moved the item. |
| `action` | `move` or `swap`. |
| `fromInventory` | The inventory the item leaves: a player id or a stash name. |
| `toInventory` | The inventory it arrives in. |
| `fromSlot` | The item leaving, or its slot number when the slot is empty. |
| `toSlot` | The item being displaced, or the destination slot number. |
| `count` | How many are moving. |

A handler that returns `false` refuses the move. Anything else, including returning nothing, allows
it.

## After a qb-inventory update

Updating `qb-inventory` overwrites both files. Apply both steps again. If you forget, the product
prints the line above again at start, so it does not fail silently.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.