Assets
Sanity provides extensible UI for managing assets, and an API for dealing with storage, resizing and deletion.
Files, like JPGs and PDFs, which exist alongside your data, are considered assets. The Sanity Studio provides a hassle-free UI for uploading assets, and an unsurprising API for dealing with all asset concerns such as storage, resizing and deletion.
We currently support image
and file
types. image
is used for all kinds of images, including SVGs, and file
is used for all other file types such as documents, audio files, zip or the like. In the future, we might provide specific support for audio and video files, but currently all non-image files belong in the file
 category.
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.
To upload assets, use the /assets/images/<dataset>
 endpoint. Once you have the image URL you can request resized versions of the original image by appending query parameters.
See the Presenting Images documentation for more details.
When you need to upload a non-image file (say a PDF or a zip file) use the /assets/files/<dataset>
 endpoint. The response is similar to the one you get from an image, but the type will be fileAsset
.
In some cases, uploading assets using the UI is impractical. Say you want to upload a ton of images. If so, you'll want to use the assets API directly.
To upload an image, do a POST request to
myProjectId.api.sanity.io/v2021-06-07/assets/images/myDataset
with your file in the request body. E.g.:
curl \
-X POST \
-H 'Content-Type: image/jpeg' \
--data-binary "@/Users/mike/images/bicycle.jpg" \
'https://myProjectId.api.sanity.io/v2021-06-07/assets/images/myDataset'
import {createClient} from '@sanity/client'
import {basename} from 'path'
import {createReadStream} from 'fs'
const client = createClient({
projectId: 'myProjectId',
dataset: 'myDatasetName',
apiVersion: '2021-08-29',
token: 'myToken'
})
const filePath = '/Users/mike/images/bicycle.jpg'
client.assets
.upload('image', createReadStream(filePath), {
filename: basename(filePath)
})
.then(imageAsset => {
// Here you can decide what to do with the returned asset document.
// If you want to set a specific asset field you can to the following:
return client
.patch('some-document-id')
.set({
theImageField: {
_type: 'image',
asset: {
_type: "reference",
_ref: imageAsset._id
}
}
})
.commit()
})
.then(() => {
console.log("Done!");
})
{
"_id": "image-abc123_0G0Pkg3JLakKCLrF1podAdE9-538x538-jpg",
"_type": "sanity.imageAsset", // type is prefixed by sanity schema
"assetId": "0G0Pkg3JLakKCLrF1podAdE9",
"path": "images/myproject/mydataset/abc123_0G0Pkg3JLakKCLrF1podAdE9-538x538.jpg",
"url": "https://cdn.sanity.io/images/myproject/mydataset/abc123_0G0Pkg3JLakKCLrF1podAdE9-538x538.jpg",
"originalFilename": "bicycle.jpg",
"size": 2097152, // File size, in bytes
"metadata": {
"dimensions": {
"height": 538,
"width": 538,
"aspectRatio": 1.0
},
"location":{ // only present if the original image contained location metadata
"lat": 59.9241370,
"lon": 10.7583846,
"alt": 21.0
}
}
}
In order to download an asset from your front-end you need to append ?dl=<asset-of-your-choice.jpg>
 to the asset URL. If you leave the filename blank, the original filename will be used if present. If the original filename is not available, the id of the file will be used instead.
// GROQ query
*[_type == "post"] {
title,
mainImage{
asset->url
}
}
// Then you can use the URL in HTML for example like this:
// <a href={`${mainImage}?dl=`}>Hero Image</a>
Deleting an asset can be performed by deleting the associated asset document.
import {createClient} from '@sanity/client'
const config = {
projectId: 'myProjectID',
dataset: 'mydataset',
apiVersion: '2021-08-29',
token: 'myToken'
}
const client = createClient(config)
client.delete('image-abc123_0G0Pkg3JLakKCLrF1podAdE9-538x538-jpg')
.then(result => {
console.log('deleted image asset', result)
})
It's important to note that while the file is deleted, the CDN might have your asset cached so it may not disappear immediately.