editor

Docs › Images and media

Attachments

Upload PDF, Office or zip files and put a download button in the post.

Put downloadable files in a post: documents for a notice, an application form. The file goes to your server and the post gets a download button with its name and size.

Try it

Code for this demo

createEditor('#editor', {
  toolbar: 'file | undo redo',
  fileMaxSize: 10 * 1024 * 1024,
  fileAccept: '.pdf,.docx,.xlsx,.zip',
  // this demo uploads nothing and returns a made-up address
  uploadFile: async (file) => 'https://example.com/files/' + encodeURIComponent(file.name),
});

Adding one

Click Attach file (file) and choose files; several at once is fine. Each shows an "Uploading…" placeholder that becomes a download button when done, or disappears with a message if the upload fails.

How files are uploaded

  • With an uploadFile function, that is used: take the file, resolve to the download address. Report progress through onProgress in the second argument.
  • Otherwise it POSTs to uploadUrl with the same uploadField (default file) and uploadHeaders as images; reply with { "url": "…" }.
  • With neither, a message says attachments need uploadFile or uploadUrl. Unlike photos, attachments are never put in the post as base64.
createEditor('#editor', {
  toolbar: 'board | file',
  fileMaxSize: 20 * 1024 * 1024,
  fileAccept: '.pdf,.docx,.xlsx,.zip',
  uploadFile: async (file, { onProgress }) => {
    const form = new FormData();
    form.append('file', file);
    const res = await fetch('/upload/attachment', { method: 'POST', body: form });
    if (!res.ok) throw new Error('Upload failed');
    return (await res.json()).url;
  },
});

Files over fileMaxSize are not uploaded and show "The file is too large (max …)". fileAccept filters the file picker; check types on the server as well.

Attachments fire the same upload:start, upload:progress, upload:success and upload:error events (Events). Their addresses are not part of getUnusedUploads().

Saved HTML

<div data-file="" style="margin: 0.6em 0">
  <a href="https://…/files/application-form.pdf" download="application-form.pdf" style="display: inline-flex; …">
    📎 <strong>application-form.pdf</strong> <span style="color: #8c959f; font-size: 0.85em">48KB</span>
  </a>
</div>

In the editor an attachment is one piece: delete it or move it with Alt+Shift+↑/↓.

Where it is

file is in the ⋯ more menu of the board and full presets.

Options

NameTypeDefaultDescription
filetoolbar itemOpens the file picker, uploads, and inserts download buttons.
uploadFile(file, { onProgress }) => Promise<string>Uploads an attachment and resolves to its download address.
uploadUrlstringPOST target when there is no uploadFile (shared with images).
uploadFieldstring'file'Form field name for the file.
uploadHeadersRecord<string, string>Headers for the POST (CSRF token …).
fileMaxSizenumber (bytes)noneLargest attachment.
fileAcceptstringany filePicker filter, e.g. '.pdf,.zip'.