One Input, Then Everything Else.

Picking files is the easy tenth of an upload feature. The other ninety percent is a queue that shows each file's progress, rejects the 300MB video before it uploads, and turns a failed transfer into a retry button instead of a support ticket. Describe your constraints and MeDo generates the whole pattern in React + Tailwind.

File Upload
File Upload

The Native Input Ends Where Your Users' Patience Begins

An input type="file" answers exactly one question — which files? — and leaves every hard question open: what happens between clicking send and the server answering. Real upload features are queues, not inputs. Files upload in parallel with independent progress, a 40MB PDF and a 2KB signature share one dropzone with different fates, and the network drops somewhere in the middle. Users judge the whole feature by those moments: a single indeterminate spinner over ten files reads as "is it frozen?", a size limit revealed only after a five-minute upload reads as hostile, and a failed batch that must be re-picked from the file dialog reads as data loss. The product is the state machine — pending, validating, uploading, done, failed, retrying — made visible per file. Generate it with your limits and endpoint stated up front, and validation errors surface at pick time in human sentences; generate it as a bare input and every one of those moments becomes a heuristic your users have to guess at.

4 个模板

可以生成的 File Upload 模板

每个模板都是真实的提示词,而不是截图。复制到任意 AI 编辑器,或在 MeDo 中运行,直接拿到 React + Tailwind 代码。

PopularClaim Documents

Validated Multi-File Dropzone With Queue

The general-purpose uploader: strict pick-time validation, a visible queue, real progress, and retry that only resends what failed.

Create a multi-file dropzone uploader. The 160px dashed dropzone highlights indigo on dragover; a visible "Browse files" button triggers a hidden native input retained for accessibility. Accept PDF, JPG, PNG up to 10MB each, 5 files total, validating at pick time with per-file rejection rows stating the exact reason; accepted files queue as rows with a 40px thumbnail, name truncated to 40 chars, human size, an XHR-driven determinate progress bar, and cancel while uploading. Upload at most 3 files concurrently, holding the rest as "Queued". On a failed request the row turns red with "Retry" that resends only that file via the same XHR path; 413 and 415 responses show the server reason with a remove button instead of retry. Completed rows turn green with a checkmark and expose the returned file key. Fire an onSubmit callback with the list of uploaded keys when every row reaches a terminal state.

在 MeDo 中尝试
MediaImage Library

Thumbnail Grid Uploader for Media

Twenty images at once, seen as a grid rather than a list — with client-side compression so an iPhone library does not become a 400MB afternoon.

Create an image uploader rendering the queue as a responsive thumbnail grid: 96px square tiles with the image preview filling the tile, a per-tile circular progress ring during upload, and a remove button on hover. Before upload, downscale images client-side to max 2048px on the long edge with canvas.toBlob at 0.82 JPEG quality and show the before/after size on the tile tooltip. Preserve EXIF orientation via createImageBitmap. Reject non-image types at pick time. Upload four files concurrently and show a header line "Uploading 3 of 18 · 12 done · 4.2MB of 31MB" with a global cancel that aborts all in-flight requests. Completed tiles get a subtle green corner check, and after completion support drag-to-reorder using the HTML5 drag events, emitting the final ordered list of URLs.

在 MeDo 中尝试
Two-phaseReview First

Queue Review Before Any Upload

For sensitive documents: nothing leaves the device until the user has seen the list, removed mistakes, and pressed Upload. Slower by one click, safer by design.

Create a two-phase uploader where dropping files only adds rows to a review list — no bytes are sent. Each pending row shows name, size, type icon and a remove button, with pick-time validation identical to a live uploader: type, 25MB per file, 10 files max, each rejection listed separately beneath the queue with its reason. The Upload button sits disabled until at least one valid file is queued and shows "Upload 4 files (38MB)" with the computed total. On upload, the same rows flip into progress state with XHR-driven bars, per-file retry on failure, and the Upload button becoming "Uploading… 2 of 4" then "Done". A "Start over" link clears the queue while nothing is in flight and is hidden once any upload has begun. Persist the picked File objects across an accidental page refresh where the browser allows it.

在 MeDo 中尝试
Large filesResume Chunked

Chunked Uploader With Pause and Resume

For the 2GB video and the hotel wifi: fixed-size chunks, a pause button, and resume that asks the server which chunks it already has instead of starting over.

Create a chunked uploader for files up to 5GB. Split each file into 8MB chunks uploaded sequentially per file via fetch with a chunk index header; track completed chunk indexes in state so the progress bar reflects true partial progress across retries. Provide Pause and Resume per file — pause stops dispatching further chunks; resume first calls a status endpoint returning which chunk indexes the server holds, then uploads only the missing ones. On chunk failure, retry that chunk up to 3 times with exponential backoff before marking the row failed with a resume action rather than restart. Show per-file speed ("12 MB/s") and estimated time remaining computed over a rolling 5-second window. When the final chunk lands, show "Processing…" with an indeterminate spinner until the server's complete callback returns the asset URL.

在 MeDo 中尝试

如何自定义你的 File Upload

Validate on pick, not on submit

Type, size and count limits should fire the moment a file enters the queue, with the specific reason per rejected file — "report.pdf: 24MB, limit is 10MB" — not a generic failure after upload begins. Rejected files that never entered the queue should still be acknowledged, or users will re-drag them and wonder.

Drive progress from XHR, not a timer

A fake progress bar that animates on setInterval tells users nothing and lies at the worst moment. Ask for XMLHttpRequest with upload.onprogress, or fetch with ReadableStream tracking if you stream, so the bar reflects real bytes. Indeterminate spinners are only honest for server-side processing after the bytes arrive.

Make failure a per-file concern with retry

Batch uploads fail partially: five files, one 500 error. The row turns red and offers Retry for that file alone while the other four complete. A whole-form error forcing users to re-pick everything converts a transient failure into a rage-quit — and for large sets, keep picked files across a page reload via File System Access where available.

Show the queue before any upload starts

An "uploading on drop" flow gives users no chance to remove the wrong file. A two-phase pattern — review the queued list, remove or reorder, then one explicit Upload button — matters anywhere files are large, personal, or easy to pick by mistake on mobile.

谁在使用 File Upload 组件

Insurance claims and KYC flows

Uploading ID documents and statements where each file is validated to strict type and size rules before upload, and a failed document retries individually while the rest of the claim proceeds.

Job application forms

A single résumé upload with instant PDF parsing preview — page count and file size shown in the row — plus portfolio links as a separate field, so the candidate sees proof the document landed before submitting.

Content management and media libraries

Dragging twenty images at once into a CMS with a thumbnail grid queue, parallel uploads capped at three to protect the connection, and per-image cancel during upload plus drag-to-reorder once done.

Support ticket attachments

A compact inline uploader inside the ticket composer accepting screenshots and logs, converting HEIC to JPG client-side before upload so agent viewers never choke on iPhone photos.

不同网站的 File Upload 方案

同一个 file upload 组件,针对它所在网站的类型做调整。

01 / 04

Insurance, Legal and KYC Forms

Strict document rules, sensitive files, and users who abandon at the first unexplained rejection. Pick-time validation with named reasons and a review-first queue are the difference between a completed claim and an abandoned one.

File Upload 的风格与变体

挑选与页面其余部分匹配的变体,然后生成它。

01 / 04

Dashed Dropzone With Browse

The canonical large dashed target with an icon, a short line of copy, and a real browse button. Make the whole zone a click target — users click dashed boxes regardless of what the copy says — while keyboard users reach the same input via the button.

在 React、Next.js、Vue 与 Svelte 中使用 File Upload

React、Next.js、Vue 3、SvelteKit、Astro 或纯 HTML —— 同一个 file upload,六种接入方式。

01 / 03

React File Upload Queue

One XHR per file, progress written straight into per-file state, and an AbortController per request so cancel is a real network cancel. Retry re-runs the same upload function for one row.

src/components/FileUpload.tsx

function uploadFile(file, onProgress) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    const ctrl = { xhr }
    xhr.upload.onprogress = (e) =>
      onProgress(Math.round((e.loaded / e.total) * 100))
    xhr.onload = () =>
      xhr.status < 400 ? resolve(JSON.parse(xhr.response)) : reject(xhr.status)
    xhr.onerror = () => reject('network')
    xhr.open('POST', '/api/upload')
    xhr.send(file)
    return ctrl
  })
}

// in the queue component:
const [rows, setRows] = useState({}) // id -> { file, progress, status }

async function start(row) {
  setRows((r) => ({ ...r, [row.id]: { ...r[row.id], status: 'uploading' } }))
  try {
    const res = await uploadFile(row.file, (p) =>
      setRows((r) => ({ ...r, [row.id]: { ...r[row.id], progress: p } })))
    setRows((r) => ({ ...r, [row.id]: { ...r[row.id], status: 'done', key: res.key } }))
  } catch {
    setRows((r) => ({ ...r, [row.id]: { ...r[row.id], status: 'failed' } }))
  }
}

如何把 File Upload 加入项目

四个步骤,从挑选 file upload 模板到上线生产环境。

01~2min

Write Down Your Actual Limits

Types, per-file size, total count, and whether upload starts on drop or after review. These are not styling choices — each one changes the queue logic the generator produces, so deciding them after generation means regenerating.

02~2min

Generate With the Endpoint Named

Paste the prompt into MeDo and replace the placeholder endpoint with your real upload route, including any auth header. Ask for XHR-based progress explicitly if you want determinate bars — fetch alone cannot report upload progress.

03~4min

Try to Break It on Bad Networks

You get React + Tailwind with a live preview. Use browser throttling to simulate a failing connection: watch a bar freeze mid-file, trigger the failure, confirm Retry resends only that file and the rest of the queue finishes untouched.

04~3min

Verify the Server Contract and Ship

Confirm each completed row receives the file key or URL your backend returns, rejections like 413 surface their reason instead of a lying retry button, and the form cannot submit until every row reaches a terminal state.

关于 File Upload 的常见问题

How do I build a drag-and-drop file upload in React?

The dropzone is a labeled region with onDragOver prevented (so the browser does not navigate to the file) and onDrop reading dataTransfer.files — but the hidden native input must remain in the DOM and be triggered by the browse button, because it is still the most accessible and most predictable path, especially on mobile where drag does not exist. MeDo generates both entry points feeding one queue, with the dragover highlight state and the focus-visible ring on the browse button included.

How do I show real upload progress per file?

Use XMLHttpRequest with its upload.onprogress event, which reports loaded and total bytes per request, and drive each row's determinate bar from that. The fetch API historically cannot report upload progress without streaming the body manually through a ReadableStream. Either way the bytes must come from the transfer itself — a CSS animation or timer-based bar will hit 90% and sit there, which is precisely when users give up.

Should files upload immediately on drop or after review?

Depends on cost of error. Immediate upload feels fast and suits screenshots and small images; a review-then-upload queue is right when files are large, personal, or easily mis-picked — users can remove the wrong document before any bytes leave the device. If you upload immediately, per-file cancel must actually abort the request client-side, not just hide the row while the bytes keep flowing.

How do I validate file type and size before uploading?

Check three things at pick time: the MIME type and extension together (either alone is spoofable or inconsistent across browsers), the File object's size against your limit, and the total count against your cap. Reject with a specific message naming the file and the violated rule, and keep the accepted rest of the batch. Server-side validation still happens — client checks are for user experience, not security.

What should happen when an upload fails mid-way?

The failed file's row turns red with an explicit Retry action that re-sends only that file, keeping any bytes progress awareness if your backend supports resumable uploads (tus or S3 multipart). Everything else in the queue is untouched. Distinguish network failures (retryable, automatic backoff is fine) from rejections — a 413 or virus-scan failure will never succeed on retry, so those get a reason and a remove action instead of a retry button that lies.

How many files should upload at once?

Cap parallelism at two to four for browser-to-server uploads. Uncapped parallel uploads compete for the same uplink and can push a large batch into timeout territory that sequential chunks would survive; too few and a twenty-image library feels stalled. Expose the limit in your prompt — "upload three files concurrently, queueing the rest" — so the generated queue models it explicitly.