Ever wish you could just stop hunting through folders to re-upload the same files to ChatGPT over and over?
Well, say hello to GPT FileDrop β a Chrome extension I whipped up that gives you a floating file sidebar right inside ChatGPT.
What It Does
- Drag files into the sidebar
- Keep up to 10 files ready to go
- Click Upload to instantly simulate dropping them into ChatGPT
- Never rummage for the same files again
- Minimize the sidebar to drag it around your screen and open it back up wherever you want it set!
Itβs a fun little quality-of-life upgrade for heavy testers, devs, or anyone building with ChatGPT.
How to Use It
- Go to
chrome://extensions/
in your Chrome browser. - Toggle on Developer Mode (top-right).
- Click Load unpacked and select the folder where the files below live.
- Visit
https://chatgpt.com/
β the sidebar should appear!
Files to Create
Paste the following into separate files inside a folder:
// content.js
(function () {
const html = `
<div id="gpt-sidebar" class="dark" style="position: fixed; top: 20px; right: 20px; width: 220px; background: #121212; color: #f5f5f5; font-family: sans-serif; border: 1px solid #333; padding: 10px; z-index: 999999; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.7); border-radius: 8px;">
<div id="sidebar-header" style="display: flex; justify-content: space-between; align-items: center; font-weight: bold; margin-bottom: 10px; cursor: move;">
<span>GPT FileDrop</span>
<button id="toggle-sidebar" style="background: #333; border: none; color: #fff; cursor: pointer; font-size: 16px; padding: 0 8px; border-radius: 4px;">β</button>
</div>
<div id="sidebar-body">
<div id="file-counter" style="text-align: center; font-weight: bold;">0/10</div>
<div id="drop-zone" style="border: 2px dashed #555; padding: 10px; margin: 10px 0; text-align: center; cursor: pointer; min-height: 60px; border-radius: 6px;">Drag files here</div>
<ul id="file-list" style="list-style: none; padding-left: 0; margin: 10px 0; max-height: 120px; overflow-y: auto;"></ul>
<div class="button-row" style="display: flex; justify-content: space-between; margin-top: 10px; flex-wrap: wrap; gap: 4px;">
<button id="upload-btn" style="flex: 1; background: #333; border: none; padding: 6px 10px; border-radius: 4px; color: white; cursor: pointer;">Upload</button>
<button id="remove-btn" style="flex: 1; background: #333; border: none; padding: 6px 10px; border-radius: 4px; color: white; cursor: pointer;">Remove</button>
<button id="clear-btn" style="flex: 1; background: #333; border: none; padding: 6px 10px; border-radius: 4px; color: white; cursor: pointer;">Clear</button>
</div>
</div>
</div>`;
const wrapper = document.createElement("div");
wrapper.innerHTML = html;
document.body.appendChild(wrapper);
const dropZone = document.getElementById("drop-zone");
const fileList = document.getElementById("file-list");
const counter = document.getElementById("file-counter");
const uploadBtn = document.getElementById("upload-btn");
const clearBtn = document.getElementById("clear-btn");
const removeBtn = document.getElementById("remove-btn");
const toggleBtn = document.getElementById("toggle-sidebar");
const sidebarBody = document.getElementById("sidebar-body");
let uploadedFiles = [];
let removeMode = false;
dropZone.addEventListener("dragover", (e) => e.preventDefault());
dropZone.addEventListener("drop", (e) => {
e.preventDefault();
const files = [...e.dataTransfer.files];
if (uploadedFiles.length + files.length > 10) {
dropZone.style.borderColor = "red";
dropZone.style.backgroundImage =
"url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMzAnIGhlaWdodD0nMzAnIHZpZXdCb3g9JzAgMCAzMCAzMCcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJz48Y2lyY2xlIGN4PScxNScgY3k9JzE1JyByPScxNScgc3R5bGU9J2ZpbGw6bm9uZTtzdHJva2U6I2ZmMDAwMDtzdHJva2Utd2lkdGg6MiddIC8+PGxpbmUgeDE9JzgnIHkxPSc4JyB4Mj0nMjInIHkyPScyMicgc3R5bGU9J3N0cm9rZTojZmYwMDAwO3N0cm9rZS13aWR0aDoyOycgLz48L3N2Zz4=')";
dropZone.style.backgroundRepeat = "no-repeat";
dropZone.style.backgroundPosition = "center";
dropZone.style.backgroundSize = "30px 30px";
setTimeout(() => {
dropZone.style.borderColor = "#555";
dropZone.style.backgroundImage = "";
}, 1500);
return;
}
uploadedFiles.push(...files.slice(0, 10 - uploadedFiles.length));
updateCounter();
renderFileList();
});
function updateCounter() {
counter.innerText = `${uploadedFiles.length}/10`;
}
function renderFileList() {
fileList.innerHTML = "";
uploadedFiles.forEach((file, index) => {
const li = document.createElement("li");
li.style.display = "flex";
li.style.justifyContent = "space-between";
li.style.alignItems = "center";
li.style.fontSize = "12px";
li.style.padding = "2px 0";
li.style.borderBottom = "1px solid #333";
const nameSpan = document.createElement("span");
nameSpan.textContent = file.name;
nameSpan.style.flex = "1";
const removeBtn = document.createElement("button");
removeBtn.textContent = "Γ";
removeBtn.style.background = "transparent";
removeBtn.style.border = "none";
removeBtn.style.color = "#f55";
removeBtn.style.cursor = "pointer";
removeBtn.style.fontWeight = "bold";
removeBtn.style.marginLeft = "6px";
removeBtn.addEventListener("click", () => {
uploadedFiles.splice(index, 1);
updateCounter();
renderFileList();
});
li.appendChild(nameSpan);
li.appendChild(removeBtn);
fileList.appendChild(li);
});
}
uploadBtn.addEventListener("click", () => {
const chatInput = document.querySelector('input[type="file"]');
if (!chatInput) {
alert("ChatGPT upload input not found.");
return;
}
const dataTransfer = new DataTransfer();
uploadedFiles.forEach((file) => dataTransfer.items.add(file));
chatInput.files = dataTransfer.files;
const evt = new Event("change", { bubbles: true });
chatInput.dispatchEvent(evt);
console.log("Files uploaded to ChatGPT.");
});
clearBtn.addEventListener("click", () => {
uploadedFiles = [];
updateCounter();
renderFileList();
});
toggleBtn.addEventListener("click", () => {
if (sidebarBody.style.display === "none") {
sidebarBody.style.display = "block";
toggleBtn.innerText = "β";
} else {
sidebarBody.style.display = "none";
toggleBtn.innerText = "+";
}
});
// Dragging minimized sidebar
const sidebar = document.getElementById("gpt-sidebar");
const header = document.getElementById("sidebar-header");
let isDragging = false;
let offsetX = 0;
let offsetY = 0;
header.addEventListener("mousedown", (e) => {
if (sidebarBody.style.display === "block") return; // only drag if minimized
isDragging = true;
offsetX = e.clientX - sidebar.getBoundingClientRect().left;
offsetY = e.clientY - sidebar.getBoundingClientRect().top;
document.body.style.userSelect = "none";
});
document.addEventListener("mousemove", (e) => {
if (!isDragging) return;
sidebar.style.left = `${e.clientX - offsetX}px`;
sidebar.style.top = `${e.clientY - offsetY}px`;
sidebar.style.right = "auto";
});
document.addEventListener("mouseup", () => {
isDragging = false;
document.body.style.userSelect = "auto";
});
})();
// manifest.json
{
"manifest_version": 3,
"name": "ChatGPT File Drop Sidebar",
"version": "1.2",
"description": "Floating sidebar to drag and auto-upload files to ChatGPT.",
"permissions": ["scripting", "activeTab"],
"host_permissions": ["https://chatgpt.com/*"],
"content_scripts": [
{
"matches": ["https://chatgpt.com/*"],
"js": ["content.js"]
}
]
}
Let me know if you try it or have ideas for fun improvements.
Now you can stop dragging files across your desktop like itβs 2003.