The media block says where uploaded files go in the repository and what URL they’ll have on the site. Everything that puts a file in your repository uses it: the media library, images pasted or dropped into the editor, image fields and AI-generated images.
media:
folder: static/images
public_path: /images
max_size_mb: 10
accept:
- image/png
- image/jpeg
- image/webp
- image/gif
- image/svg+xml| Key | What it does | Default |
|---|---|---|
folder |
Where uploads are committed, relative to the Hugo root. Prefixed with base_path if you have one. |
static/images |
public_path |
The URL prefix for those files on the built site. This is what gets written into your Markdown and frontmatter. | /images |
max_size_mb |
Upload size limit in megabytes. | 10 |
accept |
Which files are allowed. | the five image types above |
The whole block is optional, as is each key in it.
folder and public_path have to describe the same place. Hugo serves static/ at the site root, so static/images is /images on the site, static/uploads would be /uploads, and so on. If you point folder somewhere outside static/, you’re responsible for making sure Hugo actually publishes it at public_path.
accept takes MIME types (image/png), extensions (.svg) or wildcards (image/*), in any mix. To allow PDFs alongside images:
accept:
- image/*
- application/pdf
- .pdfGiving both the MIME type and the extension is a bit belt-and-braces, but browsers don’t always report a type for every file, and the extension check catches those.
The media library can create subfolders under folder and browse into them; an upload lands in whichever folder you’re looking at. Uploads are committed with the deploy.skip_ci suffix, so they don’t trigger a site build on their own. See Media library for the rest.