Backend · Skill
Add file uploads
add-file-uploads
Adds file uploads to a web app - pick storage such as S3, R2, Supabase Storage or UploadThing, upload straight from the browser with signed URLs, check file type and size on the server, and keep private files behind signed links. Use when the user wants image uploads, profile photos, attachments, or a drag-and-drop upload box.
Works with: Any AI Not yet model-tested; testing Jan 2027
Paste it into ChatGPT, Claude, Gemini or any AI chat, then tell it about your project. How it works
Install in Claude Code, Cursor or Codex (optional)
Only for AI coding tools that read skill folders. Run one line in a terminal, in your project folder. It downloads this skill's text files from TheSkillVault and nothing else; you can read them first with “View raw SKILL.md”.
Claude Code (all your projects)
curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/add-file-uploads/raw' -o ~/'.claude/skills/add-file-uploads/SKILL.md'Cursor (this project)
curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/add-file-uploads/raw' -o '.cursor/skills/add-file-uploads/SKILL.md'Codex and other Agent Skills tools (this project)
curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/add-file-uploads/raw' -o '.agents/skills/add-file-uploads/SKILL.md'
Or connect the whole library over MCP
Add TheSkillVault to Cursor or add this to your app's MCP settings (read-only; help):
{
"mcpServers": {
"theskillvault": {
"url": "https://theskillvault.ai/mcp"
}
}
}Uploads look simple but touch storage, security and cost. The safe pattern: the server decides what may be uploaded, the browser sends the file straight to storage.
When to use
- Users need to upload avatars, images, PDFs or attachments.
- Uploads through your own API are slow or hit size limits.
- You need private files only the owner can open.
Steps
- Choose storage: S3 or Cloudflare R2 for full control, Supabase Storage if you use Supabase, or UploadThing for the quickest setup.
- Decide the rules: allowed types, max size, and whether files are public or private.
- Add a server route that checks the signed-in user and the rules, then returns a short-lived signed upload URL.
- In the browser, use a file input or drop zone, check type and size, then upload with the signed URL and show progress.
- Save a record in your database: owner id, storage key, type, size and created date.
- Generate storage keys yourself (such as
users/{id}/{random}.jpg). Never use the raw file name as the path. - For private files, serve them through short-lived signed download URLs after checking the owner.
- Resize or compress images on upload or with an image service before showing them.
- Clean up storage when the record is deleted.
Gotchas
- Never trust the browser's file type. Check size and content type on the server or in the signed URL policy.
- Do not let uploads land in a public bucket by default. Public files can be found and shared.
- Uploaded HTML or SVG files can carry scripts. Serve them as downloads or block them.
- Set storage limits and lifecycle rules so a bug cannot fill your bill.
Portability
Works with any framework. If you use a different storage provider such as Google Cloud Storage or Azure Blob instead, the signed URL pattern is the same.
Example prompt
"Add profile photo uploads to my Next.js app using Cloudflare R2, limited to 5 MB images, with each user only able to replace their own photo."
Done when
- Allowed files upload with progress and appear in the app.
- Wrong types and oversized files are rejected by the server.
- Private files open only for their owner through signed links.
---
House original by TheSkillVault (CC-BY-4.0).
Licence
Licence: CC BY 4.0. Attribution when you reuse it: From TheSkillVault, https://theskillvault.ai, CC BY 4.0