Storage & Uploads
File uploads backed by the local filesystem or any S3-compatible provider, with public and private buckets.
Overview
SiteKnock's storage layer gives you a single, consistent way to handle file uploads whether you store files on the local filesystem or in S3-compatible object storage. It supports separate public and private areas so sensitive files stay protected.
Configure storage
"storage": {
"provider": "s3", // "fs" | "s3"
"uploads": true,
"s3Bucket": "my-app", // Public bucket
"s3PrivateBucket": "", // Optional private bucket
"s3Region": "us-east-1",
"s3Endpoint": "http://localhost:9000", // MinIO / R2 / custom
"publicUrl": "http://localhost:9000/my-app"
}
Providers
| Provider | Description |
|---|---|
Filesystem (fs) | Files on a mounted volume. Simple, single-instance. Public assets live under apps/frontend/public/assets/*. |
S3-compatible (s3) | Works with AWS S3, Cloudflare R2, and MinIO. Horizontally scalable — the right choice for multi-replica production. |
Public vs. private
| Type | Access | Use case |
|---|---|---|
| Public | Direct URL | Logos, Open Graph images, marketing assets |
| Private | API-proxied | User uploads, sensitive documents |
Leave s3PrivateBucket empty to disable the private area.
Upload flow
Upload
The frontend sends a file to the backend's upload endpoint.
Store
The backend stores it through the storage layer and returns a storage key (e.g. assets/branding/logo.svg).
Display
The frontend uses the key to display the file via its public URL or an API proxy for private files.
The image upload control
The kit includes a complete image upload component with drag-to-pan preview positioning, resize-before-save, upload/remove/adjust actions, and configurable preview shapes (circle, square, wide, tall). It's used throughout Studio and the dashboard.
Local development
pnpm compose:dev:up includes a MinIO container (an S3-compatible server) so you can develop against S3 locally. Its console is at http://localhost:9001.