File

Content blocks

File

Share any file from an email or a page: a PDF, a text file, a CSV, an XML feed, an HTML page, a Word, Excel or PowerPoint file, a ZIP. Users upload it in the block, and a Preview switch can show the file right in the editor.

What the reader gets#

The exported email holds a download card: the file's type badge, its name and size, and a button with your link. Email apps cannot show a PDF or run a page, so the file itself is never put in the email. Preview only changes what you see while building.

Preview#

Turn on Show preview in the editor in the block's Preview section. The file then appears on the canvas and in Preview mode; the height is yours to set (200 to 900 px).

KindExtensionsWhat you see
PDFpdfThe browser's PDF viewer, scrollable page by page
CSV / TSVcsv, tsvA table with a sticky header and row numbers. Scroll to read every row: more rows load as you scroll, so a file of any size stays smooth
XMLxmlIndented, each element on its own line, scrollable to the end
HTMLhtml, htmRendered as a page, in a sandbox that runs no scripts
Text and JSONtxt, md, log, jsonAs text (JSON is indented), scrollable to the end
Mediapng, jpg, gif, webp, mp4, webm, mp3, wavAn image, a video or an audio player
Othersdoc, docx, xls, xlsx, ppt, pptx, zipNo preview. They still download from the email
The preview reads the file in the browser, so the host of the file must allow it (CORS). A file served from your own bucket through uploadFile below does. If a file cannot be read, the block says so and links to the file. Files over 10 MB show their first 10 MB, and say so.

Uploading#

The block takes any file through your upload handler, the same assets.onImageUpload that images use, called with kind: "file". Without a handler the editor refuses a file upload (a base64 file would bloat the email). The editor also checks the file against the email size limit when you set one.

tsserver.ts
// your backend route: POST /upload  (multipart field "file")
const stored = await admin.uploadFile({
  buffer: file.buffer, filename: file.originalname, contentType: file.mimetype, scopeId: req.user.orgId
});
// -> { url, contentType, name, size }   (the editor puts these in the block)

admin.uploadFile in email-craft-sdk is built for this. Per-tenant key prefix (scopeId is required), 20 MB cap, and the type is judged from the file's bytes, never from what the browser claims. It accepts PDF, text, CSV, JSON, XML, HTML, RTF, Word, Excel, PowerPoint, ODT, ODS, ZIP and PNG, JPEG, GIF, WebP, AVIF images, and refuses scripts, programs and SVG (use uploadAsset for SVG, which cleans it).

Pages and feeds (HTML, XML) are stored as plain text and as a download, so opened from your bucket they never run as a page on that origin. Previews of them are rendered by the editor, inside the sandbox above.

Block values#

PropertyControlsDefault
urlThe file's public link (set by the upload),
nameFile name shown on the card(from the link)
mime / sizeType and size in bytes, set by the upload,
button_labelThe download button textDownload
previewShow the file in the editor (never in the email)false
preview_heightPreview height, 200–900 px420
background_color / border_color / border_radius / paddingThe card#ffffff / #d9dce5 / 12 / 16
button_color / button_text_colorThe download button#14213d / #ffffff
container_paddingSpace above and belowtoken.spacing

The File block is part of the free editor. The MCP server and Cloud API know it as file (see get_block_schema); the quality check warns when a file block has no file.