An image upload does more than move bytes. Before anything leaves your browser Leed checks the format and the size, offers you a crop, and fingerprints the file twice so it can tell you if you already have this picture. After the upload it describes the image with a vision model and writes the result into the alt text field for you to correct. This page covers all of it, in the order it happens.
Four ways to start an upload
New asset → Image in the Assets panel of the Design workspace is the direct route. The button sits at the top of the panel and is there whether or not you already have an asset open; it opens a four-way chooser, and picking Image opens the Upload Image dialog. This is the only path that takes you to the new asset when it finishes.
Dragging a file from your desktop onto any screen in the CMS opens the same dialog with your file already loaded. Leed routes the drop by MIME type, so an image goes to this flow rather than becoming a document — uploading by drag and drop covers the overlay and what happens when you drop inside a page you are editing.
Your logo, favicon and profile picture reuse this same dialog with its controls trimmed. So does the light/dark documentation logo in Settings.
The three paths do not behave identically, and the differences are the ones people trip over:
- Library upload
- Drag and drop
- Logo, favicon or profile picture
The full dialog: drop area, Name field, Cancel and Submit. Every step on this page applies — the format and size checks, the crop step for raster images, the duplicate check, and the AI alt text written after the upload. When it finishes you land on the new asset’s canvas.
Identical to the library upload once the dialog is open, including the crop step and the duplicate check, because it is the same dialog with your file prefilled. The one addition is placement: a file dropped inside the page editor is also inserted at the point you let go.
Logo and favicon skip the crop step and skip the duplicate check entirely, because they are not library assets — they are committed straight to your site repository and recorded on the company record. The Name field is hidden, and the dialog is titled for what you are replacing (Upload Logo, Upload Favicon, Upload Dark Logo).
A profile picture is a library asset. It keeps the crop step and the duplicate check; only the Name and Alt Text are filled in for you, from your own name, and the asset is tagged with a reserved system label so it does not clutter the ordinary label picker.
The Feature Image field on a page is not in this list, because it does not upload. It opens a picker of images you already have. Upload first, then pick — page settings covers the field itself.
Formats and the size limit
Five image types are accepted. Anything else — a TIFF, a BMP, a HEIC straight off a phone — is refused before the dialog will let you continue.
| Format | MIME type | Extension | Crop offered | Duplicate check | AI alt text |
|---|---|---|---|---|---|
| PNG | image/png | .png | yes | yes | yes |
| JPEG | image/jpeg | .jpeg, .jpg | yes | yes | yes |
| GIF | image/gif | .gif | yes, with a caveat | yes | yes |
| WebP | image/webp | .webp | yes | yes | yes |
| SVG | image/svg+xml | .svg | no | no | no |
SVG is the outlier on three counts, all for the same reason: there is nothing to rasterise. There is no crop surface, no perceptual fingerprint to compare, and the vision model is never called — an SVG’s alt text is yours to write from the start. The GIF caveat is the browser’s, not Leed’s, and is explained under cropping.
An image must be strictly under 10MB. A file at exactly 10MB is refused, not accepted. The check runs before the file is read, hashed, cropped or sent anywhere, so a rejection costs you nothing but the message.
The two rejections you can see, verbatim:
Valid file types are: png,jpeg,gif,webp,svg
Image is 12.4MB. Images must be under 10MB.The size in that second message rounds up to a tenth of a megabyte, deliberately, so a file that is barely over never reads as though it were exactly at the limit. A 10,485,761-byte file reports as 10.1MB, not 10.0MB. (Dropping a file rather than browsing for it produces a differently worded format rejection — Unsupported image type. Supported image formats: png, jpeg, gif, webp, svg. — because the drag-and-drop path has to work out which upload flow you meant before it can complain.)
Cropping
Pick a raster image and the dialog shows you a crop surface before anything else: your image with a frame you can drag over it, the line Draw a box to crop, or skip to keep the full image., and two buttons — Skip crop and Apply crop.
The crop is free-form. There is no fixed aspect ratio to choose, no preset sizes and no rotate — draw whatever rectangle you want, or draw nothing. Apply crop stays disabled until you have drawn a box, so skipping is always a single click and you can never accidentally apply an empty crop.
Two things about where it appears and what it affects:
- The crop step is offered on the library upload and drag-and-drop paths only. The logo, favicon and immediate-upload paths skip it, as does any SVG.
- Both fingerprints are computed on the file that is actually uploaded — after the crop, not before. So duplicate detection always reflects what you are really sending, and a crop of an image you already hold reads as a different file rather than as a duplicate of the original.
Why my GIF did not crop
The crop is performed in your browser by drawing the selection to a canvas and re-encoding it in the source format. Some formats cannot be re-encoded that way — animated GIF is the usual case — and when the browser refuses, Leed falls back to uploading your original file unchanged rather than uploading corrupt or single-frame bytes.
So the upload succeeds and the image is intact; the crop is simply not applied. If you need a cropped GIF, crop it in an image editor before uploading.
Duplicate detection
Before an upload starts, Leed computes two fingerprints in your browser and asks the server whether it has seen either of them.
The first is a SHA-256 of the exact bytes — an all-or-nothing match on the file itself. The second, for raster images only, is a perceptual hash: a small signature derived from the picture’s structure rather than its bytes, so the same photograph resized, re-saved or re-compressed still resolves to a nearly identical signature. Leed compares your file against the media you already hold and treats a close-enough perceptual match as a near-duplicate.
If anything matches, you get a dialog headed Possible duplicate image, reading We found existing media that looks identical or similar to what you’re uploading, with your file previewed under Your upload and each match listed beneath it with a thumbnail, its name and a chip:
| Chip | How it is detected | Typical cause | What you can do |
|---|---|---|---|
identical | the SHA-256 of your file matches an existing asset byte for byte | the same file uploaded twice, often from a shared folder or a second machine | reuse the one you have; uploading again gives you two identical assets to keep in step |
similar | the perceptual hashes are close enough to be the same picture | the same photo resized, re-exported at a different quality, or re-saved by another tool | check which one is the higher-quality original and keep that one |
What you can do about it depends on where you started. In the editor’s asset picker each match is a button — the heading reads Existing matches (select one to reuse) — so you can adopt the existing asset and skip the upload. In the library, matches are shown but not selectable; your choices are Cancel or Not a duplicate — upload anyway.
Alt text, written for you
Every non-SVG image you upload is sent to a vision model and described, and the description is saved to the asset’s Alt Text field. This happens on the server immediately after the asset row is created, so you will usually see the real text by the time the asset canvas finishes loading.
Until it arrives the field holds a placeholder — Please regenerate alt text... for a raster image, Insert alt text here... for an SVG. If you see the first of those on an asset that has been around a while, the description failed; press the AI sparkle beside the Alt Text label to try again. You can rewrite the field freely at any time, and it autosaves like every other asset field.
The sparkle is hidden on SVG assets, and the endpoint behind it accepts images only: asking it to describe a video or a document is refused outright. It is one of the AI helpers described in AI in the editor, none of which is plan-gated.
Why it matters
Alt text is what a screen reader announces in place of the picture, and what a search engine reads. Leed copies it into the alt attribute of every placement of that image, on every page, so a good description is written once and pays off everywhere — and a bad one is wrong everywhere too.
What happens after Submit
Nothing is uploaded through Leed’s API. Your browser asks the backend for a one-time direct-upload URL, sends the bytes straight to the image CDN, and only then asks Leed to create the asset row pointing at what it just stored. That is why a large upload does not tie up the CMS, and why the size check runs where it does.
flowchart TD
PICK["Image chosen, dropped or browsed"] --> MIME{"An accepted<br/>image type?"}
MIME -->|no| REJECT["Refused.<br/>Nothing is read or sent"]
MIME -->|yes| SIZE{"Strictly<br/>under 10MB?"}
SIZE -->|no| REJECT
SIZE -->|yes| VEC{"Raster image,<br/>on a crop-enabled path?"}
VEC -->|"no — SVG, logo,<br/>favicon"| SVGSKIP["Crop skipped"]
VEC -->|yes| CROP["Crop step:<br/>Skip crop or Apply crop"]
CROP --> HASH
SVGSKIP --> ISSVG{"SVG?"}
ISSVG -->|yes| UP
ISSVG -->|no| HASH
HASH["SHA-256 plus perceptual hash,<br/>computed on the final bytes"] --> SEARCH["Duplicate search"]
SEARCH -->|"match found"| DLG["Possible duplicate image dialog"]
SEARCH -->|"none, or the check failed"| UP
DLG -->|"Not a duplicate —<br/>upload anyway"| UP
DLG -->|Cancel| STOP["Nothing uploaded"]
UP["One-time direct-upload URL,<br/>bytes go straight to the image CDN"] --> ROW["Asset row created"]
ROW --> ALT["Vision model writes the alt text"]
ROW --> NAV["You land on the new asset"]
From there the asset is ordinary. Label it, mark it approved, copy its embed snippet or see which pages use it on asset details and usage. Uploading needs asset:create, which the Content Writer role and above carry — roles and permissions has the ladder.
One original is all you ever upload. Leed serves it in several widths and in whatever modern format the visitor’s browser accepts, which is covered in asset delivery and protection; those widths have names and exact pixel dimensions, and a template or a page can ask for one of them by name, which is the image variants and responsive images ladder. When you place the image, its size and caption ride along as attributes on the Leed Markdown image — see images and figures.