Files and images
A file field keeps an upload with its record, under the same rules. Images are resized, cropped and converted when asked for, so a thumbnail costs a thumbnail's bytes.
Uploading
const photos = sluurp.collection("photos");
await photos.upload(record.id, "image", input.files[0]);
// or make the record and upload in one step
await photos.createWithFile({ caption: "Sports day" }, "image", file);Over HTTP it is POST /api/files/{collection}/{id}/{field}, multipart, in a part called file. Uploading is a change to the record, so its update rule decides; reading the file is reading the record, so its view rule does.
Images at the size they’re shown
img.src = photos.fileUrl(record.id, "image", { w: 320, h: 320, fit: "cover" });
img.srcset = photos.srcset(record.id, "image", [400, 800, 1200]);| Parameter | |
|---|---|
w, h | Width and height, up to 4000 |
fit | contain (the default: all of it, inside the box) or cover (fill the box, cropped) |
format | jpeg, png or webp |
q | Quality, for jpeg and webp |
A resized image is made once and kept, keyed by the file and the size, so a new upload never shows the old picture. The kept copies can be deleted at any time; they are made again when asked for.
A file that isn’t public is fetched with the sign-in: fileObjectUrl(id, field) gives an address an <img> can use, and fileText(id, field) its text.
Where files are kept
On disk, beside the database. For more than one server, set a bucket on any S3-compatible service (AWS, Cloudflare R2, MinIO, Backblaze) in the environment. Every upload then goes to the bucket too, and a server that doesn’t have a file fetches it from there:
SLUURP_S3_BUCKET=school-files
SLUURP_S3_ENDPOINT=https://<account>.r2.cloudflarestorage.com
SLUURP_S3_REGION=auto
SLUURP_S3_ACCESS_KEY_ID=…
SLUURP_S3_SECRET_ACCESS_KEY=…How much may be stored
A project can have a storage allowance, and each person one too, set in the admin UI. An upload that would go past it is refused before it’s written. Without one, there’s no limit.
The admin UI shows an image as itself in its record, and lets you replace or remove it.