<baht-upload>
Uploads to an HTTP endpoint the moment a file is picked or dropped. The endpoint returns where
it stored the file, and that URL becomes the value. Nothing waits for a form submit and no host
code is needed: the whole contract is attributes. Use <baht-file> when you only want to
capture a File, or when the upload has to go through a registry function.
Basic
This page has no upload endpoint, so picking a file here shows the error state with Retry. Point url at your API to see it succeed.
Events (name)
<baht-upload url="/api/uploads" label="Attachment" accept=".pdf,image/*" max-size="10485760"></baht-upload>Pre-filled with files on record
Feed value with the URLs you already stored; chips render from them (name = URL basename). Remove emits the rest.
Events (name)
<baht-upload url="/api/uploads" label="Attachments" multiple="true"></baht-upload>
<script>
const el = document.querySelector('baht-upload');
el.value = [
"/uploads/contract-2026.pdf",
"/uploads/site-plan.png"
];
</script>The endpoint contract
Section titled “The endpoint contract”| Request | |
|---|---|
| method | method attribute, default POST |
| body | multipart/form-data, the file under field-name (default file) |
| headers | headers property, e.g. { Authorization: 'Bearer …' }, plus with-credentials for cookies |
| Response | |
|---|---|
2xx + JSON |
URL read at response-key (default url; dotted paths such as data.location work) |
2xx + text |
the body is the URL |
| anything else | baht-upload-error; the chip shows “Upload failed” with Retry, value unchanged |
el.addEventListener('baht-change', (e) => { e.detail.value; // 'https://cdn.example/uploads/scan.pdf' (string[] when multiple) e.detail.files; // [{ name, size, type, url }]});el.headers = { Authorization: `Bearer ${token}` };| Name | Type | Default | Description |
|---|---|---|---|
url | string | '' | Endpoint that receives the file and returns its stored URL. Required. |
method | string | 'POST' | HTTP method for the upload request. |
field-name | string | 'file' | Form-data key the file is sent under. |
response-key | string | 'url' | Where the stored URL lives in a JSON response (dotted path). Empty = the body itself. |
headersJS | Record<string, string> | {} | Extra request headers (e.g. Authorization). |
with-credentials | boolean | false | Send cookies on cross-origin requests. |
valueJS | string | string[] | null | null | Stored URL(s): string, string[] when multiple, or null. |
label | string | '' | Visible label. |
hint | string | '' | Helper text; defaults to the accept / size limits. |
accept | string | undefined | — | Native accept filter (.pdf,image/*). |
multiple | boolean | false | Allow several files; the value becomes an array. |
max-size | number | undefined | — | Reject files over this many bytes before sending. |
disabled | boolean | false | Disable the control |
required | boolean | false | Show required mark |
error | string | null | null | Validation message to display; marks the control invalid. |
Events
Section titled “Events”| Event | detail | Description |
|---|---|---|
name | CustomEvent | |
baht-change | { value, files: UploadedFile[] } | After every successful upload, remove, or clear() |
baht-upload-start | { file } | A request was sent |
baht-upload-progress | { file, loaded, total, percent } | Upload progress |
baht-upload-error | { file, status, message } | Non-2xx, network failure, or a body without a URL (status 0) |
Methods
Section titled “Methods”clear() empties the value. Nothing is deleted on the server.