How to Handle HTML Form File Uploads Without a Backend
Learn how to accept file uploads on static HTML forms using presigned direct cloud uploads. No server backend code, PHP, or function limits required.
How do you upload files from an HTML form without a backend?
To upload files from an HTML form without a backend, request a short-lived presigned upload URL via POST /api/v1/f/[key]/presign, upload the file bytes directly to private cloud storage via PUT, and submit the form with the resulting file IDs. Form2Lead handles storage, validation, and email alerts automatically.
Why File Uploads Fail on Static Hosting
Static sites hosted on GitHub Pages, Netlify, or Vercel cannot process binary file uploads natively. Running custom serverless functions usually hits 4.5 MB request body ceilings and burns costly bandwidth quotas. Direct presigned uploads solve this by separating file bytes from form data.
The Two-Step Presigned Architecture
Instead of proxying binary files through a web server, the browser requests a temporary signed PUT URL from Form2Lead, uploads the file directly to private cloud storage, and includes the resulting fileId in the final form submission POST.
<!-- 1. Frontend form with attachment input -->
<form id="quote-form">
<input type="text" name="client_name" required placeholder="Name" />
<input type="file" id="spec_sheet" accept=".pdf,.png,.jpg" />
<input type="text" name="_gotcha" style="display:none" />
<button type="submit">Submit Request</button>
</form>
<script>
// 2. Client-side presign and direct cloud upload
document.getElementById('quote-form').addEventListener('submit', async (e) => {
e.preventDefault();
const file = document.getElementById('spec_sheet').files[0];
const fileIds = [];
if (file) {
// Step A: Request presigned upload URL
const presign = await fetch('https://form2lead.com/api/v1/f/YOUR_FORM_ID/presign', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fileName: file.name, contentType: file.type, sizeBytes: file.size })
}).then(res => res.json());
// Step B: Upload file bytes directly to storage
await fetch(presign.uploadUrl, { method: 'PUT', headers: { 'Content-Type': file.type }, body: file });
fileIds.push(presign.fileId);
}
// Step C: Submit form data with attached file IDs
const payload = Object.fromEntries(new FormData(e.target));
payload._f2l_files = fileIds;
await fetch('https://form2lead.com/api/v1/f/YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: JSON.stringify(payload)
});
alert('Form submitted with attachment!');
});
</script>Security: Private Storage & Malware Blocking
Form2Lead automatically enforces strict security: executable files (.exe, .sh), HTML, and SVG files are rejected to prevent malware and stored-XSS attacks. All uploads are stored in private encrypted storage and accessed solely via 15-minute expiring signed capability URLs.
How-To Q&A
Do file uploads work without writing any backend server code?
Yes. The entire upload process occurs directly from the browser to Form2Lead’s private cloud storage. Your static HTML site requires zero server-side code or cloud function maintenance.
What is the maximum file size supported?
Form2Lead supports up to 5 MB per file on Basic, 10 MB on Starter, and 20 MB on Growth, with a 25 MB platform hard cap.
How do I access uploaded files in my submissions?
Uploaded files appear with download links in your dashboard inbox, in instant email alert notifications, and as download URLs in CSV exports.