diff --git a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java
index 392cec24c..f9d2ace46 100644
--- a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java
+++ b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java
@@ -34,7 +34,6 @@ import com.nukkitx.nbt.NbtMap;
 import com.nukkitx.nbt.NbtMapBuilder;
 import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
 import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
-import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
 import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
 import org.geysermc.connector.entity.type.EntityType;
 import org.geysermc.connector.network.session.GeyserSession;
@@ -102,13 +101,7 @@ public class ItemFrameEntity extends Entity {
             ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue());
             NbtMapBuilder builder = NbtMap.builder();
 
-            String blockName = "";
-            for (StartGamePacket.ItemEntry startGamePacketItemEntry : ItemRegistry.ITEMS) {
-                if (startGamePacketItemEntry.getId() == (short) itemEntry.getBedrockId()) {
-                    blockName = startGamePacketItemEntry.getIdentifier();
-                    break;
-                }
-            }
+            String blockName = ItemRegistry.getBedrockIdentifer(itemEntry);
 
             builder.putByte("Count", (byte) itemData.getCount());
             if (itemData.getTag() != null) {
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java
index 56ed2d6e0..1f3af019f 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java
@@ -221,6 +221,23 @@ public class ItemRegistry {
                 .stream().filter(itemEntry -> itemEntry.getJavaIdentifier().equals(key)).findFirst().orElse(null));
     }
 
+    /**
+     * Finds the Bedrock string identifier of an ItemEntry
+     *
+     * @param entry the ItemEntry to search for
+     * @return the Bedrock identifier
+     */
+    public static String getBedrockIdentifer(ItemEntry entry) {
+        String blockName = "";
+        for (StartGamePacket.ItemEntry startGamePacketItemEntry : ItemRegistry.ITEMS) {
+            if (startGamePacketItemEntry.getId() == (short) entry.getBedrockId()) {
+                blockName = startGamePacketItemEntry.getIdentifier(); // Find the Bedrock string name
+                break;
+            }
+        }
+        return blockName;
+    }
+
     /**
      * Gets a Bedrock {@link ItemData} from a {@link JsonNode}
      * @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java
index 13725522b..864e9fe03 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java
@@ -41,6 +41,7 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.network.session.GeyserSession;
 import org.geysermc.connector.network.translators.ItemRemapper;
+import org.geysermc.connector.network.translators.world.block.BlockTranslator;
 import org.geysermc.connector.utils.FileUtils;
 import org.geysermc.connector.utils.LanguageUtils;
 import org.geysermc.connector.utils.MessageUtils;
@@ -154,9 +155,43 @@ public abstract class ItemTranslator {
             itemData = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem);
         }
 
+        if (nbt != null) {
+            // Translate the canDestroy and canPlaceOn Java NBT
+            ListTag canDestroy = nbt.get("CanDestroy");
+            String[] canBreak = new String[0];
+            ListTag canPlaceOn = nbt.get("CanPlaceOn");
+            String[] canPlace = new String[0];
+            canBreak = getCanModify(canDestroy, canBreak);
+            canPlace = getCanModify(canPlaceOn, canPlace);
+            itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), itemData.getTag(), canPlace, canBreak);
+        }
+
         return itemData;
     }
 
+    /**
+     * Translates the Java NBT of canDestroy and canPlaceOn to its Bedrock counterparts.
+     * In Java, this is treated as normal NBT, but in Bedrock, these arguments are extra parts of the item data itself.
+     * @param canModifyJava the list of items in Java
+     * @param canModifyBedrock the empty list of items in Bedrock
+     * @return the new list of items in Bedrock
+     */
+    private static String[] getCanModify(ListTag canModifyJava, String[] canModifyBedrock) {
+        if (canModifyJava != null && canModifyJava.size() > 0) {
+            canModifyBedrock = new String[canModifyJava.size()];
+            for (int i = 0; i < canModifyBedrock.length; i++) {
+                // Get the Java identifier of the block that can be placed
+                String block = ((StringTag) canModifyJava.get(i)).getValue();
+                // Sometimes this is done but it's still valid
+                if (!block.startsWith("minecraft:")) block = "minecraft:" + block;
+                // Get the Bedrock identifier of the item and replace it.
+                // This will unfortunately be limited - for example, beds and banners will be translated weirdly
+                canModifyBedrock[i] = BlockTranslator.getBedrockBlockIdentifier(block).replace("minecraft:", "");
+            }
+        }
+        return canModifyBedrock;
+    }
+
     private static final ItemTranslator DEFAULT_TRANSLATOR = new ItemTranslator() {
         @Override
         public List<ItemEntry> getAppliedItems() {
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/ShulkerBoxItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/ShulkerBoxItemTranslator.java
index 0645c9807..a9930f698 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/ShulkerBoxItemTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/ShulkerBoxItemTranslator.java
@@ -26,7 +26,6 @@
 package org.geysermc.connector.network.translators.item.translators.nbt;
 
 import com.github.steveice10.opennbt.tag.builtin.*;
-import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
 import org.geysermc.connector.network.session.GeyserSession;
 import org.geysermc.connector.network.translators.ItemRemapper;
 import org.geysermc.connector.network.translators.item.ItemEntry;
@@ -51,13 +50,7 @@ public class ShulkerBoxItemTranslator extends NbtItemStackTranslator {
             boxItemTag.put(new ByteTag("WasPickedUp", (byte) 0)); // ???
 
             ItemEntry boxItemEntry = ItemRegistry.getItemEntry(((StringTag) itemData.get("id")).getValue());
-            String blockName = "";
-            for (StartGamePacket.ItemEntry startGamePacketItemEntry : ItemRegistry.ITEMS) {
-                if (startGamePacketItemEntry.getId() == (short) boxItemEntry.getBedrockId()) {
-                    blockName = startGamePacketItemEntry.getIdentifier(); // Find the Bedrock string name
-                    break;
-                }
-            }
+            String blockName = ItemRegistry.getBedrockIdentifer(boxItemEntry);
 
             boxItemTag.put(new StringTag("Name", blockName));
             boxItemTag.put(new ShortTag("Damage", (short) boxItemEntry.getBedrockData()));
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java
index 8da09f6f3..81c86c307 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java
@@ -28,15 +28,12 @@ package org.geysermc.connector.network.translators.world.block;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
-import com.nukkitx.nbt.NBTInputStream;
-import com.nukkitx.nbt.NbtList;
-import com.nukkitx.nbt.NbtMap;
-import com.nukkitx.nbt.NbtMapBuilder;
-import com.nukkitx.nbt.NbtType;
-import com.nukkitx.nbt.NbtUtils;
+import com.nukkitx.nbt.*;
 import it.unimi.dsi.fastutil.ints.*;
 import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.network.translators.world.block.entity.BlockEntity;
 import org.geysermc.connector.utils.FileUtils;
@@ -52,6 +49,11 @@ public class BlockTranslator {
 
     private static final Int2IntMap JAVA_TO_BEDROCK_BLOCK_MAP = new Int2IntOpenHashMap();
     private static final Int2IntMap BEDROCK_TO_JAVA_BLOCK_MAP = new Int2IntOpenHashMap();
+    /**
+     * Stores a list of differences in block identifiers.
+     * Items will not be added to this list if the key and value is the same.
+     */
+    private static final Object2ObjectMap<String, String> JAVA_TO_BEDROCK_IDENTIFIERS = new Object2ObjectOpenHashMap<>();
     private static final BiMap<String, Integer> JAVA_ID_BLOCK_MAP = HashBiMap.create();
     private static final IntSet WATERLOGGED = new IntOpenHashSet();
     private static final Object2IntMap<NbtMap> ITEM_FRAMES = new Object2IntOpenHashMap<>();
@@ -152,11 +154,11 @@ public class BlockTranslator {
 
             // Used for adding all "special" Java block states to block state map
             String identifier;
-            String bedrock_identifer = entry.getValue().get("bedrock_identifier").asText();
+            String bedrockIdentifier = entry.getValue().get("bedrock_identifier").asText();
             for (Class<?> clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) {
                 identifier = clazz.getAnnotation(BlockEntity.class).regex();
                 // Endswith, or else the block bedrock gets picked up for bed
-                if (bedrock_identifer.endsWith(identifier) && !identifier.equals("")) {
+                if (bedrockIdentifier.endsWith(identifier) && !identifier.equals("")) {
                     JAVA_ID_TO_BLOCK_ENTITY_MAP.put(javaRuntimeId, clazz.getAnnotation(BlockEntity.class).name());
                     break;
                 }
@@ -164,9 +166,15 @@ public class BlockTranslator {
 
             BlockStateValues.storeBlockStateValues(entry, javaRuntimeId);
 
+            String cleanJavaIdentifier = entry.getKey().split("\\[")[0];
+
+            if (!cleanJavaIdentifier.equals(bedrockIdentifier)) {
+                JAVA_TO_BEDROCK_IDENTIFIERS.put(cleanJavaIdentifier, bedrockIdentifier);
+            }
+
             // Get the tag needed for non-empty flower pots
             if (entry.getValue().get("pottable") != null) {
-                BlockStateValues.getFlowerPotBlocks().put(entry.getKey().split("\\[")[0], buildBedrockState(entry.getValue()));
+                BlockStateValues.getFlowerPotBlocks().put(cleanJavaIdentifier, buildBedrockState(entry.getValue()));
             }
 
             if ("minecraft:water[level=0]".equals(javaId)) {
@@ -297,6 +305,14 @@ public class BlockTranslator {
         return BEDROCK_TO_JAVA_BLOCK_MAP.get(bedrockId);
     }
 
+    /**
+     * @param javaIdentifier the Java identifier of the block to search for
+     * @return the Bedrock identifier if different, or else the Java identifier
+     */
+    public static String getBedrockBlockIdentifier(String javaIdentifier) {
+        return JAVA_TO_BEDROCK_IDENTIFIERS.getOrDefault(javaIdentifier, javaIdentifier);
+    }
+
     public static int getItemFrame(NbtMap tag) {
         return ITEM_FRAMES.getOrDefault(tag, -1);
     }