Uploading base64 images to Sanity and resolving a 400 error

16 replies
Last updated: Mar 28, 2022
I'm looking at the docs
client.assets.upload(type: 'file' | image', body: File | Blob | Buffer | NodeStream, options = {}): Promise<AssetDocument>
Can I upload base64 to to sanity? or no
AI Update

Yes, you can upload base64 images to Sanity, but you need to convert the base64 string first. The client.assets.upload() method accepts File | Blob | Buffer | NodeStream, but not raw base64 strings directly.

Here's what you need to do:

1. Strip the data URI prefix

If your base64 string includes the data URI header (like data:image/jpeg;base64,), you need to remove it first. This header often causes the "Invalid image, could not read metadata" error.

2. Convert to Buffer

Convert the base64 string to a Buffer:

const base64Data = imageBase64.replace(/^data:image\/\w+;base64,/, '');
const uploadBuffer = Buffer.from(base64Data, 'base64');

await client.assets.upload('image', uploadBuffer, {
  contentType: 'image/jpeg', // or whatever your image type is
  filename: 'myimage.jpg'
});

Alternative: Use a blob utility

You can also use a package like blob-util to convert base64 to a Blob, which several developers in the Sanity community have found helpful for this exact use case.

The key issue is that Sanity's asset pipeline needs to read the image metadata to process it, and it can only do that from actual binary data (Buffer/Blob), not from a base64-encoded string. Once you convert it properly, the upload should work fine.

For reference, according to the Sanity documentation on images, Sanity supports JPEG, PNG, and WebP as processed output formats, with GIF and SVG passing through untouched. Make sure your contentType option in the upload method matches your actual image format.

I'm trying to upload base64 image to sanity
const handleOnSave = async(imageObj) => {
    console.log(imageObj, 'imageObj')
    const image = imageObj.imageBase64;
    setImageAsset(image);
    await client.assets.upload("image", image, {contentType: imageObj.mimeType, fileName: imageObj.fullName});
    closeImgEditor();
  }

but get 400 error
this the meta data, mimeType and fullName
Do you mind posting the error here as text rather than an image? Thanks!
Upload failed: Bad Request - Invalid image, could not read metadata
Can you upload this as a string or file type?
To be clear are you sending the base64 string to the asset upload or the file?
Per the assets documentation , you’ll need to convert that to a supported or tolerated image format, upload the blob as a string or file, and if you then want to view the string in the studio you’ll need to make a custom component to interpret it.
Though Sanity lets you import a wide range of image formats like TIFF and SVG our currently supported image formats for processed output are: JPEG, PNG and WebP.
GIF and SVG pass through the image pipeline untouched, but if you want them scaled they will need to be output as one of the three formats above.
Yes
user Y
So I need to convert the base64 string into a blob?
I had a similar issue but realized my base64 string had the header describing the image type (
data:image/jpeg;base64,
) and that was causing problems. Once I stripped it off and converted it to a buffer (
_let_ uploadBuffer = _await_ Buffer.from(imageBase64, 'base64');
) the images uploaded just fine.
I was going to write "You need to use one of the asset types listed in the docs or you need to use the "file upload" to upload a blob/string etc" but if you have had positive outcome with base64
user S
then I would most certainly attempt that approach first,
user F
! Great point out Dan, thanks
i ended up using this package https://www.npmjs.com/package/blob-util
fixed the problem, thanks for the response and support though
cool plugin, thanks for the tip

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?