sethucms
Using it

Images and files

Images and PDFs can be stored in the connected database and used from any field that holds a file. The first adapter that offers this is Firestore. Other databases do not offer it, and the admin app only shows the upload button when the connection can store files.

Status: tested against a fake Firestore. Try it against a real project before relying on it.

Endpoints

MethodPathWhoPurpose
POST/v1/connections/{id}/fileseditor, adminUpload raw bytes
GET, HEAD/v1/files/{id}/{fileId}anyone with the link (public) or any token (private)Download
DELETE/v1/connections/{id}/files/{fileId}adminRemove

A file field in a record holds a small object such as { "asset": "...", "url": "...", "alt": "..." }. The admin app shows a preview, a Replace button and a Private checkbox. The raw object is available behind Edit as code.

What is allowed

PNG, JPEG, WebP, GIF, SVG and PDF, up to 4 MB (serverless hosts cap a request at about 4.5 MB).

Safety rules

  • The type comes from the bytes. The gateway reads the first bytes and refuses a file whose content does not match what the caller said, so a web page cannot be slipped in as an image.
  • Hidden data is cut out. Images lose camera and GPS data, author and software tags, comments, thumbnails and anything appended after the end of the image. The picture is not decoded or re-compressed, so quality is unchanged. Only the rotation is kept, so phone photos stay upright.
  • PDFs that can run something are refused: JavaScript, launch actions, embedded files, forms that submit data and rich media. This is a filter, not a guarantee. A PDF that cannot be read well enough to check is refused.
  • Malformed files are refused. The gateway never guesses about a file it cannot parse.
  • Public links cannot be guessed (128 random bits), but anyone with the link can read the file, like any "anyone with the link" share. A file uploaded with X-File-Access: private is served only to a caller who sends a valid token, and looks missing to everyone else.

Limits

SettingDefaultMeaning
SETHUCMS_FILE_STORAGE_MB100Total storage per connection
SETHUCMS_FILE_DAILY_MB50Upload volume per caller per day
SETHUCMS_FILE_DAILY_COUNT100Uploads per caller per day

Moving files out of Sanity

Content that still links to cdn.sanity.io can be copied into the connection with the sync script (sync-sanity-to-cms.mts, kept in the website project that owns the Sanity content). Run it as a dry run first, then with --apply --force. After it runs, the records point at gateway links instead.