# Uploads and assets

> Where HTML Clay stores uploaded files, file size and type limits, how documents link to uploads, and how to move or share them.

Source: https://htmlclay.com/docs/uploads/

When a document uploads an image or attachment through ClayJS's [`upload`](https://clayjs.com/docs/plugins/upload/) or [`cms`](https://clayjs.com/docs/plugins/cms/) plugin, HTML Clay stores the file on your computer and returns a path the document can save in its HTML.

## Where uploads are stored

HTML Clay stores uploaded files in a library folder at `~/htmlclay/uploads`, creating it on first use.

Inside `~/htmlclay/uploads`, each document gets its own subfolder named `assets-<slug>`, where `<slug>` is derived from the document's filename with `.htmlclay`, `.html`, `.htm`, or `.xhtml` removed. For example, a document named `My Board.v2.htmlclay` stores its uploads in:

```text
~/htmlclay/uploads/assets-my-board-v2/
```

Each uploaded file is saved as `<stem>-<digest><ext>`. The digest is an HMAC-SHA256 hash of the file's contents (at least 32 hex characters) keyed by a 32-byte secret at `~/htmlclay/uploads/.library-key`. Uploading the exact same file twice writes a single file on disk. The `.library-key` file is never served over HTTP and never included in exports.

You cannot add `~/htmlclay/uploads` itself to [Trusted Folders](https://htmlclay.com/docs/guide/trusted-folders/), though an enclosing folder such as `~/htmlclay` or your home folder can be trusted.

## Size limit and allowed file types

Each uploaded file can be up to **25 MB** (with an extra 64 KiB allowed for the multipart request wrapper so a 25 MB file passes).

- A file over 25 MB is refused with HTTP `413` (`File too large (max 25MB)`, code `too-large`).
- An empty file is refused with HTTP `400` (`Empty file`).

To prevent stored scripts from running on your origin, HTML Clay refuses HTML, XML, and JavaScript file types: `.html`, `.htm`, `.shtml`, `.xhtml`, `.xht`, `.htmlclay`, `.xml`, `.xsl`, `.xslt`, `.mathml`, `.mml`, `.rss`, `.atom`, `.rdf`, `.js`, `.mjs`, `.cjs`, `.ecma`, and any file whose MIME type is HTML, XML, or JavaScript. These return HTTP `415` (`That kind of file cannot be uploaded`, code `unsupported-type`).

`.svg` files are accepted, but HTML Clay serves them as a file download rather than rendering them inline as a document.

## How pages reference uploads

A page uploads a file by calling `clay.upload(file)` from the [`upload` plugin](https://clayjs.com/docs/plugins/upload/), which sends a same-origin `POST` request to `/_/upload/{token}`. On success, HTML Clay responds with:

```json
{
  "ok": true,
  "msg": "Uploaded",
  "msgType": "success",
  "uploads": [
    {
      "name": "photo-a1b2c3d4e5f6...jpg",
      "url": "/_/uploads/assets-my-board-v2/photo-a1b2c3d4e5f6...jpg",
      "bytes": 184320
    }
  ]
}
```

Write `uploads[0].url` directly into your `<img>`, `<audio>`, `<video>`, or `<a>` element. HTML Clay serves `GET /_/uploads/{path...}` on every folder address without requiring a save token, so browser media elements load it directly. Requests for hidden files, `..` segments, absolute paths, or non-regular files return `404 Not Found`.

## Moving or sharing a document

### Moving or renaming on the same computer

Because every folder address in HTML Clay serves `/_/uploads/...` from `~/htmlclay/uploads`, existing upload URLs in your document keep working when you rename the document or move it to another folder inside your home directory.

### Sharing with another person or computer

Because uploaded files live in `~/htmlclay/uploads` (and any sibling `assets-<name>` folder next to the document), copying the `.htmlclay` file alone does not copy its attachments.

To share a document along with its images and attachments, use [Export as zip](https://htmlclay.com/docs/export/) in the tray menu. HTML Clay packages the document, its sibling `assets-<name>` folder, and every file it references from `~/htmlclay/uploads` into one `.zip` archive in `~/Downloads`, rewriting `/_/uploads/...` references in the exported copy to relative `uploads/...` paths so the archive works on any computer.
