Skip to content

Media

A media root holds the images and files editors upload. Add one to a workspace with Config.media() and set the workspace's mediaDir to the folder the files are written to. Link to uploads with the Image, File and Link fields.

import {Config} from 'alinea'

export const main = Config.workspace('My site', {
  source: 'content',
  mediaDir: 'public/media',
  roots: {
    pages: Config.root('Pages'),
    media: Config.media()
  }
})

Editors upload files in the media root of the dashboard and organize them in folders.

What's stored

Every upload is saved in two places:

  • The file itself goes to mediaDir, named after the original file plus the id of its entry: public/media/landscape.2V4c3kRS.jpg.

  • A media entry is stored with your content, in the media root: content/media/landscape.json. It holds the title, the file location, the extension and size, a content hash and, for images, the width and height, the average color, a thumbhash placeholder, the focal point and the alt text.

Folders are entries too. Links store the id of the media entry, so moving or renaming a file in the dashboard doesn't break them.

Urls

Your site serves uploads at /admin/file/<folders>/<name>.<extension>, below the adminPath of your config. withAlinea forwards those requests to your Alinea handler, which serves the public copy of the file. When a file is moved or renamed, its old url keeps working. Set mediaUrl on the workspace to add a prefix, for example when two workspaces could have files with the same name.

So keep mediaDir inside your public folder, and don't change it once there are uploads: entries store file locations relative to it.

Options

Config.media(options) takes the same options as Config.root, with media-specific behaviour:

  • i18n: translate the alt text of files. Files themselves aren't localised: every locale uses the same file, and editors enter an alt text per locale. Image links return the alt text in the locale of the entry you queried. Add a fallback function to choose which locales to try when a translation is missing: fallback: locale => ['en'].

  • children: folders that always exist.

  • icon, orderChildrenBy and view, as for other roots.

The label of a media root is always "Media". A workspace can have several media roots; uploads that don't target a specific folder go to the first one.

Limits and production

  • Set maxUploadSize in your config (in bytes) to refuse larger uploads.

  • Committing uploads to Git works well for images and documents, less so for large videos. When you deploy with your own backend, uploads can go to S3-compatible storage instead, see Self-hosted.