Alinea includes a built-in media library that integrates directly with your content. Uploaded files are stored in your repository (or an external storage provider) and referenced from content entries using typed link fields. The media library supports both images and arbitrary files, with automatic preview generation and blur-hash thumbnails for images.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/alineacms/alinea/llms.txt
Use this file to discover all available pages before exploring further.
Setting up a media root
Every workspace that needs file uploads must include a media root. Create one withConfig.media() and add it to the workspace’s roots map.
cms.config.ts
Config.media() returns a pre-configured root that uses the built-in MediaLibrary and MediaFile types. Only one media root per workspace is needed.
mediaDir
The workspace option that controls where uploaded files are physically stored on disk. Defaults to
public, which makes files directly accessible by Next.js’s static file serving. Paths inside entries are stored relative to this directory.Customising the media directory
Built-in media types
Alinea registers two reserved types automatically — you cannot define your own types with these names.MediaLibrary
Represents a folder in the media library. The dashboard uses this type to render the folder tree in the media explorer. Each MediaLibrary entry can contain other MediaLibrary entries (nested folders).
MediaFile
Represents a single uploaded file. Alinea creates one MediaFile entry per uploaded file and populates it with metadata fields automatically:
| Field | Type | Description |
|---|---|---|
title | string | File name |
path | string | Path relative to the workspace root |
location | string | Physical path on disk |
previewUrl | string | Public URL used for in-dashboard preview rendering |
extension | string | File extension, e.g. '.png' |
size | number | File size in bytes |
hash | string | Content hash for deduplication |
width | number | Image width in pixels (images only) |
height | number | Image height in pixels (images only) |
preview | string | Base64 WebP preview data URI (images only) |
averageColor | string | Hex dominant colour (images only) |
focus | {x: number; y: number} | Editor-set focal point (images only) |
thumbHash | string | Blur-hash for placeholder rendering |
Referencing media in your types
UseField.image() and Field.file() to create media link fields inside your content types.
Field.image()
Renders an image picker that filters the media library to image file types (.jpg, .jpeg, .png, .gif, .webp, etc.).
Using Field.image()
ImageLink object:
ImageLink shape
Field.file()
Renders a file picker for non-image files (documents, PDFs, archives, etc.).
Using Field.file()
FileLink object:
FileLink shape
Querying media entries
QueryMediaFile and MediaLibrary entries just like any other type.
Listing all images in the media library
Listing media folders
Image preview generation
When an image is uploaded through the dashboard, Alinea automatically:- Resizes the image to at most 100×100 pixels and encodes it as a ThumbHash — a compact blur placeholder.
- Computes the dominant average colour from the ThumbHash data.
- Generates a 160×160 WebP preview and stores it as a base64 data URI in the
previewfield. - Records the original
widthandheight.
createPreview utility (alinea/core/media/CreatePreview), which uses the sharp package server-side. No additional configuration is needed — it runs automatically during upload.
sharp is an optional peer dependency. If it is not installed, image previews will not be generated and width, height, preview, thumbHash, and averageColor will remain empty. Install it with your package manager to enable previews.Using blur-hash placeholders
ThethumbHash and averageColor fields are designed for use in <img> loading states. A thumbHash can be decoded client-side using the thumbhash library to render a coloured blur that matches the image content before it loads.
Rendering a blur placeholder