TheShipStack Docs
Features

File Uploads

S3-compatible file uploads with Better Upload — Backblaze B2 in prod, MinIO locally.

TheShipStack uses Better Upload with an S3-compatible backend.

Local setup

MinIO runs via Docker Compose and is used automatically in development. See Local Development for access details.

Production setup

In production, files go to Backblaze B2. Create a B2 bucket (set to public) and an App Key, then set the storage env vars. See Deployment for details.

Upload route

The upload handler lives in app/api/upload/route.ts. It validates the request and returns a pre-signed URL for direct browser-to-storage upload.

Uploading a file from the client

import { useUpload } from 'better-upload/client'

export function AvatarUpload() {
  const { upload, isUploading } = useUpload()

  async function handleFile(file: File) {
    const { url } = await upload({ file, route: 'avatar' })
    // url is the permanent public URL of the uploaded file
  }

  return <input type="file" onChange={(e) => handleFile(e.target.files![0])} />
}

Adding a new upload route

In app/api/upload/route.ts, add a new route config alongside the existing ones:

documents: {
  maxFileSize: '10mb',
  allowedFileTypes: ['application/pdf'],
},

On this page