Media
Configuration
Every option of the Media module, the image size presets, and the upload refusals they produce.
All options are optional and live in the module's config in antelope.config.ts.
antelope.config.ts
"dms-media": {
source: { type: "package", package: "@antelopejs/dms-media", version: "^0.5.0" },
config: {
storage: "media",
rootAcl: [{ subject: { kind: "permission", id: "articles.page" }, rights: ["read"] }],
allowedMimetypes: ["image/*", "application/pdf"],
storageQuotaBytes: 10_000_000_000,
publicBaseUrl: "${@api.API_PUBLIC_BASE_URL}",
presets: [
{ id: "thumb", width: 300, height: 300, fit: "cover", format: "webp", quality: 80 },
],
},
},
Options
| Option | Type | Default | Description |
|---|---|---|---|
storage | string | default storage | Named interface-file-storage backend. |
rootAcl | AclEntry[] | [] | Rights every folder without its own ACL inherits. Owners hold every right anyway, and members only reach the linked folders of their pages; an entry here opens the whole library to its subject. |
allowedMimetypes | string[] | images, video, audio, PDF, Office, OpenDocument, RTF, plain text, Markdown, CSV | File types the library accepts; image/* matches a prefix. HTML, XHTML and PHP are always refused, by type or extension. |
storageQuotaBytes | number | none | Storage plan: the overview measures usage against it, and presign refuses an upload that would go past it. |
publicBaseUrl | string | DMS apiBaseUrl | Public URL of the API, the origin serving /media/.... Copied links and the Delivery tab start with it. Request headers are never read. The dashboard's origin serves /media/... too: the module declares /media/** to the frontend server, which forwards it with the member's session. |
presets | MediaPresetConfig[] | thumb, preview | Named image sizes. Replaces the defaults; keep a thumb preset, the explorer uses it for grid thumbnails. |
An AclEntry is { subject: { kind: "permission" | "role", id }, rights: ("read" | "write" | "manage")[] }. Rights imply weaker ones: manage ⇒ write ⇒ read.
Image size presets
| Field | Type | Description |
|---|---|---|
id | string | Name used in URLs: /media/<assetId>/<presetId>/<filename>. |
width, height | number | Target box, in pixels. Either can be left out. |
fit | "cover" | "contain" | "inside" | How the image fits the box. Images are never upscaled. |
format | "webp" | "jpeg" | "png" | "avif" | Output format. |
quality | number | Encoder quality. |
The defaults are thumb (300 × 300, cover, WebP 80) and preview (1600 wide, inside, WebP 82). Changing a preset invalidates its renderings naturally, through a new cache key; a daily job sweeps the stale ones.
Upload refusals
A refused upload answers { reason, message }, which the upload queue explains in the member's language:
| Reason | Status | Cause |
|---|---|---|
type_not_allowed | 415 | Not in allowedMimetypes, or HTML / XHTML / PHP |
field_type | 415 | The linked folder feeds a field that accepts fewer types (listed in accepted) |
quota | 413 | The upload would go past storageQuotaBytes (remaining and quota given) |
invalid_image | 422 | On confirm: a declared image that does not decode; the staged file is deleted |
Scheduled jobs
| Job | When | What |
|---|---|---|
dms-media-purge-staging | Every hour | Deletes uploads staged more than 24 hours ago and never confirmed |
| Derivatives sweep | Daily | Removes renderings of presets that changed |
| Activity retention | — | Library events (media_events) are kept 90 days |