uploads

Accept file uploads with size limits, store them on disk or in the cloud, and show progress in the browser.

BackendClient and Server

What it is

@kitr/uploads takes files from people. In the browser, useUpload checks size and type, then sends with progress. On the server, mountUploads checks again, stores the bytes through a driver and answers with a record for your database.

Runs on both sides. For files on the user's own device, use files.

Install

kitr add uploads

First time? Run npm i -g @kitr/kitr once. Inside a project, the global kitr runs your project's own version.

Adds @kitr/uploads, its provider, config/uploads.ts and mountUploads(server) in server/main.ts, which serves POST and GET /api/uploads. Adds server first if missing. Every change.

Quick start

The server already accepts files. Add a component that sends one:

// app/features/orders/invoice-upload.tsx
import { useUpload } from '@kitr/uploads/react'

export function InvoiceUpload() {
  const { send, progress, uploading, error, files } = useUpload({
    accept: ['application/pdf'],
    maxSize: 10 * 1024 * 1024,
  })
  return (
    <div>
      <input type="file" accept="application/pdf" onChange={(e) => send(e.target.files).catch(() => {})} />
      {uploading ? <progress value={progress} max={100} /> : null}
      {files[0] ? <a href={files[0].url}>{files[0].name}</a> : null}
      {error ? <p role="alert">{error.message}</p> : null}
    </div>
  )
}

Grace picks invoice-1042.pdf. The hook checks it against the rules, posts it as multipart/form-data and updates progress from 0 to 100. The server checks the rules again, writes the file to storage/uploads/<id>/invoice-1042.pdf, and answers:

{
  "files": [
    {
      "id": "72eb7790-7c62-4c37-9167-d9989b7ac10f",
      "name": "invoice-1042.pdf",
      "size": 48213,
      "type": "application/pdf",
      "url": "/api/uploads/72eb7790-7c62-4c37-9167-d9989b7ac10f/invoice-1042.pdf"
    }
  ]
}

The link appears from files. A file over 10 MB, or not a PDF, is refused before a byte is sent, and error says why. Next in the guide: Upload your first file.

Built on

kitr adds the shared rules, progress and cancellation, the hook, the error shape, the file record, safe serving headers and the driver interface.

Problems it solves

Further reading