Skip to main content

File uploads with FormData

Use case

Upload files to a server using multipart form data.

Smallest working example

import { createClient } from '@parcely/core'

const http = createClient({ baseURL: 'https://api.example.com' })

const form = new FormData()
form.set('avatar', fileBlob, 'avatar.png')
form.set('caption', 'Profile photo')

await http.post('/upload', form)

Auto-conversion from plain objects

When a plain object contains File or Blob values, parcely automatically converts it to FormData:

await http.post('/upload', {
avatar: fileBlob, // File or Blob triggers auto-conversion
caption: 'Profile photo',
tags: ['profile', 'v2'], // Arrays are serialised per formDataSerializer
metadata: { width: 200, height: 200 }, // Nested objects use bracket notation
}, {
formDataSerializer: 'brackets', // default
})

Serialisation modes

ModeArray resultNested object result
'brackets' (default)tags[]=profile&tags[]=v2metadata[width]=200
'indices'tags[0]=profile&tags[1]=v2metadata[width]=200
'repeat'tags=profile&tags=v2metadata[width]=200

Axios equivalent

// axios:
const form = new FormData()
form.append('avatar', file)
await http.post('/upload', form)

// parcely (identical pattern):
const form2 = new FormData()
form2.set('avatar', file)
await http.post('/upload', form2)

Axios auto-converts plain objects with File/Blob to FormData via formSerializer. parcely uses formDataSerializer with the same default ('brackets').

Notes and gotchas

  • Auto-FormData triggers only when the body is a plain object (prototype is Object.prototype or null) with at least one File or Blob value.
  • FormData instances are passed through without modification.
  • Content-Type (with multipart boundary) is set automatically. Do not set it manually.
  • If you manually set Content-Type, parcely respects it and skips auto-conversion.