Docs

Media library

Upload, browse, and manage files. Images, video, PDF — any file type. Served at /orbiter/media/[id].

Uploading

In the admin sidebar, click Media. Drag files onto the page or click Upload. Multiple files can be uploaded at once.

Files can also be uploaded directly from the editor's media picker — the image is inserted immediately after upload.

Serving media in Astro

<img src={`/orbiter/media/${post.data.image}`} alt={post.data.title} />

The /orbiter/media/[id] route is injected by @a83/orbiter-integration. It serves the file from whatever backend is configured — BLOB from SQLite, file from disk, or a 302 redirect to a CDN URL. No change needed in your templates when switching backends.

Adding external links

To reference a file hosted elsewhere (Dropbox, Google Drive, Cloudinary, any public URL) without downloading it, use the External link tab in the editor's image picker or POST /api/media/add-link.

Orbiter makes a HEAD request to detect the mime type, then stores only the URL in _media.url. Serving issues a 302 redirect — no proxy, no egress cost.

Folders

Assign files to folders at upload time. The library can be filtered by folder. Folder names are free-form strings stored in _media.folder.

Alt text

Add alt text at upload time or edit it later in the media library. The alt field is returned alongside the media metadata in the API.

Deleting files

Select a file and click Delete. For the local backend, the file is also removed from disk. For the github backend, a deletion commit is made via the GitHub API. For s3, a DeleteObject request is sent. Blob and external-link items are removed from _media in the pod.

Responsive variants & focal point

Add query parameters to any image URL to get a resized, re-encoded or cropped version, generated on demand and cached:

ParamValues
wWidth in px, rounded up to one of 160, 320, 480, 640, 800, 1024, 1280, 1600, 2000 (never enlarged)
fmtwebp, avif or jpeg
arAspect ratio to crop to: 1:1, 4:3, 3:2, 16:9, 2:1, 3:4, 2:3, 9:16
<img
  src="/orbiter/media/{id}?w=800&fmt=webp"
  srcset="/orbiter/media/{id}?w=480&fmt=webp 480w,
          /orbiter/media/{id}?w=800&fmt=webp 800w,
          /orbiter/media/{id}?w=1280&fmt=webp 1280w"
  sizes="(min-width: 800px) 800px, 100vw" alt="…" />

In the media library, Focal point on an image lets you click the important part. Crops with ar keep that point in frame instead of cutting from the centre — so a 16:9 banner doesn't behead the person at the edge of a portrait.

  • Needs sharp, which Astro projects already have. Without it, or for SVG/GIF/video/PDF, the original is served unchanged.
  • Because widths and ratios come from fixed lists, the number of variants per image is bounded. At most two are rendered at once; when many new variants are requested at the same moment the extra requests get 503 with Retry-After. Rendered variants are kept in a 64 MB in-memory cache and served with a one-day cache lifetime.
  • Variants are not stored in the pod — they are cheap to regenerate and always follow the current focal point.

Usage, unused files and broken references

Every card shows whether the file is used (used in 3 entries) or unused; hover for the entry titles. The filter bar adds Unused and Broken refs. Deleting a file that is in use warns you first and names the entries. Broken refs lists entries that point at a media file that no longer exists.

References are found by the file's id inside entry content, so they are recognised wherever they are stored — picker fields, image blocks, Markdown links to /orbiter/media/<id>. Entries in the trash count as references. Editors restricted to some collections see the counts but not the titles of entries they may not open.

API access

GET  /api/media              — list all files (no binary data)
GET  /api/media/usage        — { usage, unused, broken }
PUT  /api/media/:id          — { alt?, focal_x?, focal_y? } (focal in 0..1, null clears)
GET  /api/media/:id/raw      — serve the file
POST /api/media              — upload (multipart/form-data)
POST /api/media/import-url   — server-side fetch from a URL
POST /api/media/add-link     — store an external URL reference
DELETE /api/media/:id        — delete

Last updated Edit this page on GitHub ↗