diff --git a/src/gameComponents/Image/Image.jsx b/src/gameComponents/Image/Image.jsx
index 98f42ee5..cf4d7961 100644
--- a/src/gameComponents/Image/Image.jsx
+++ b/src/gameComponents/Image/Image.jsx
@@ -67,7 +67,8 @@ const Image = ({
   id: currentItemId,
 }) => {
   const { currentUser, localUsers: users } = useUsers();
-  const { register } = useItemInteraction("place");
+  const { register: registerPlace } = useItemInteraction("place");
+  const { register: registerDelete } = useItemInteraction("delete");
   const { getItemList } = useItemActions();
 
   const wrapperRef = React.useRef(null);
@@ -131,7 +132,6 @@ const Image = ({
           itemIds,
           shouldHoldItems: item.holdItems,
         });
-
         if (item.linkedItems !== newLinkedItems) {
           return {
             linkedItems: newLinkedItems,
@@ -142,16 +142,45 @@ const Image = ({
     [currentItemId, getItemList, setState]
   );
 
+  const onDeleteItem = React.useCallback(
+    (itemIds) => {
+      setState((item) => {
+        const safeLinkedItems = item.linkedItems || [];
+        const newLinkedItems = safeLinkedItems.filter(
+          (id) => !itemIds.includes(id)
+        );
+
+        if (safeLinkedItems.length !== newLinkedItems.length) {
+          return {
+            linkedItems: newLinkedItems,
+          };
+        }
+      }, true);
+    },
+    [setState]
+  );
+
+  React.useEffect(() => {
+    const unregisterList = [];
+    if (currentItemId) {
+      unregisterList.push(registerPlace(onPlaceItem));
+    }
+
+    return () => {
+      unregisterList.forEach((callback) => callback());
+    };
+  }, [currentItemId, onPlaceItem, registerPlace]);
+
   React.useEffect(() => {
     const unregisterList = [];
     if (currentItemId) {
-      unregisterList.push(register(onPlaceItem));
+      unregisterList.push(registerDelete(onDeleteItem));
     }
 
     return () => {
       unregisterList.forEach((callback) => callback());
     };
-  }, [currentItemId, onPlaceItem, register]);
+  }, [currentItemId, onDeleteItem, registerDelete]);
 
   return (
     <Wrapper ref={wrapperRef}>
diff --git a/src/gameComponents/useGameItemActions.jsx b/src/gameComponents/useGameItemActions.jsx
index ea37b901..17eeb2aa 100644
--- a/src/gameComponents/useGameItemActions.jsx
+++ b/src/gameComponents/useGameItemActions.jsx
@@ -2,7 +2,12 @@ import React from "react";
 
 import { useTranslation } from "react-i18next";
 import { toast } from "react-toastify";
-import { useItemActions, useUsers, useSelectedItems } from "react-sync-board";
+import {
+  useItemActions,
+  useUsers,
+  useSelectedItems,
+  useItemInteraction,
+} from "react-sync-board";
 
 import {
   shuffle as shuffleArray,
@@ -53,6 +58,7 @@ export const useGameItemActions = () => {
     swapItems,
     getItems,
   } = useItemActions();
+  const { call: callPlaceInteractions } = useItemInteraction("place");
 
   const { t } = useTranslation();
 
@@ -125,7 +131,7 @@ export const useGameItemActions = () => {
 
       batchUpdateItems(
         ids,
-        (item) => {
+        () => {
           const newItem = {
             x: newX,
             y: newY,
@@ -136,8 +142,9 @@ export const useGameItemActions = () => {
         },
         true
       );
+      callPlaceInteractions(ids);
     },
-    [batchUpdateItems, getItemListOrSelected]
+    [batchUpdateItems, getItemListOrSelected, callPlaceInteractions]
   );
 
   // Stack selection to Top Left
@@ -162,7 +169,7 @@ export const useGameItemActions = () => {
 
       batchUpdateItems(
         ids,
-        (item) => {
+        () => {
           const newItem = {
             x: newX,
             y: newY,
@@ -173,8 +180,9 @@ export const useGameItemActions = () => {
         },
         true
       );
+      callPlaceInteractions(ids);
     },
-    [batchUpdateItems, getItemListOrSelected]
+    [batchUpdateItems, getItemListOrSelected, callPlaceInteractions]
   );
 
   // Align selection to a line
@@ -198,8 +206,9 @@ export const useGameItemActions = () => {
         },
         true
       );
+      callPlaceInteractions(ids);
     },
-    [getItemListOrSelected, batchUpdateItems]
+    [getItemListOrSelected, batchUpdateItems, callPlaceInteractions]
   );
 
   // Align selection to an array
@@ -235,8 +244,9 @@ export const useGameItemActions = () => {
         },
         true
       );
+      callPlaceInteractions(ids);
     },
-    [getItemListOrSelected, batchUpdateItems]
+    [getItemListOrSelected, batchUpdateItems, callPlaceInteractions]
   );
 
   const snapToPoint = React.useCallback(
@@ -256,8 +266,9 @@ export const useGameItemActions = () => {
         },
         true
       );
+      callPlaceInteractions(itemIds);
     },
-    [batchUpdateItems]
+    [batchUpdateItems, callPlaceInteractions]
   );
 
   const roll = React.useCallback(
@@ -386,8 +397,10 @@ export const useGameItemActions = () => {
       swapItems(ids, shuffledItems);
 
       playAudio(shuffleAudio, 0.5);
+
+      callPlaceInteractions(ids);
     },
-    [getItemListOrSelected, swapItems]
+    [getItemListOrSelected, callPlaceInteractions, swapItems]
   );
 
   const randomlyRotateSelectedItems = React.useCallback(
@@ -492,12 +505,13 @@ export const useGameItemActions = () => {
       );
       if (reverseOrder) {
         reverseItemsOrder(itemIdsToFlip);
+        callPlaceInteractions(itemIds);
       }
       if (itemIdsToFlip.length) {
         playAudio(flipAudio, 0.2);
       }
     },
-    [batchUpdateItems, getItems, reverseItemsOrder]
+    [batchUpdateItems, callPlaceInteractions, getItems, reverseItemsOrder]
   );
 
   // Toggle flip state
diff --git a/src/utils/item.js b/src/utils/item.js
index a40aec0c..aa07176e 100644
--- a/src/utils/item.js
+++ b/src/utils/item.js
@@ -117,35 +117,49 @@ export const getHeldItems = ({
   itemIds,
   shouldHoldItems,
 }) => {
-  const safeCurrentLinkedItems = currentLinkedItemIds || [];
+  const safeCurrentLinkedItems = Array.isArray(currentLinkedItemIds)
+    ? currentLinkedItemIds
+    : [];
+
   if (shouldHoldItems) {
-    let before = true;
-    const afterItemIds = itemList
-      .filter(({ id }) => {
-        const result = !before && itemIds.includes(id);
-        if (id === currentItemId) {
-          before = false;
-        }
-        return result;
+    const currentItemIndex = itemList.findIndex(
+      ({ id }) => id === currentItemId
+    );
+    const currentItemLayer = itemList[currentItemIndex].layer || 0;
+
+    const afterMap = Object.fromEntries(
+      itemList.map(({ id, layer = 0 }, index) => {
+        return [
+          id,
+          layer > currentItemLayer ||
+            (layer === currentItemLayer && index > currentItemIndex),
+        ];
       })
-      .map(({ id }) => id);
+    );
+    const afterItemIds = itemIds.filter((id) => afterMap[id]);
+
+    const afterCurrentLinkedItemIds = (currentLinkedItemIds || []).filter(
+      (id) => afterMap[id]
+    );
+
     const newHeldItems = Object.entries(
-      areItemsInside(element, afterItemIds, safeCurrentLinkedItems, true)
+      areItemsInside(element, afterItemIds, afterCurrentLinkedItemIds, true)
     )
       .filter(([, { inside }]) => inside)
       .map(([itemId]) => itemId);
+
+    const oldLinked = new Set(safeCurrentLinkedItems);
+    const newLinked = new Set(newHeldItems);
+
     if (
-      safeCurrentLinkedItems.length !== newHeldItems.length ||
-      !safeCurrentLinkedItems.every((itemId) => newHeldItems.includes(itemId))
+      newLinked.size !== oldLinked.size ||
+      !Array.from(oldLinked).every((id) => newLinked.has(id))
     ) {
       return newHeldItems;
     }
   } else {
-    if (
-      !Array.isArray(safeCurrentLinkedItems) ||
-      safeCurrentLinkedItems.length !== 0
-    ) {
-      return [];
+    if (safeCurrentLinkedItems.length !== 0) {
+      return safeCurrentLinkedItems;
     }
   }