Importing images to Sanity - possible workaround using ndjson

8 replies
Last updated: May 2, 2020
Hello. Trying to understand importing assets to sanity. After reading https://www.sanity.io/docs/importing-data am I right that images can only be imported by referencing them as part of a document? I would like to just import the images to make them available to the authors when they build content but I don't know how they're going to use them.
AI Update

You're actually not quite right about that! While the documentation you're reading focuses on importing images within documents, you can absolutely upload images to Sanity directly without attaching them to a document first. The images will then be available in your asset library for authors to use later.

Uploading images without documents

You can upload standalone images using the Assets API. When you upload an image, Sanity automatically creates a sanity.imageAsset document that stores the metadata, but you don't need to create or reference it from any other document. These assets live independently in your dataset and are available for authors to browse and use.

Using the JavaScript client

import {createClient} from '@sanity/client'

const client = createClient({
  projectId: 'myProjectId',
  dataset: 'myDatasetName',
  apiVersion: '2021-08-29',
  token: 'myToken'
})

// Upload the image - it's now available in your asset library
client.assets
  .upload('image', createReadStream('/path/to/image.jpg'), {
    filename: 'bicycle.jpg'
  })
  .then(imageAsset => {
    console.log('Uploaded!', imageAsset._id)
    // The image is now in your library, ready for authors to use
  })

Using the HTTP API directly

You can also POST directly to the Assets API endpoint:

curl -X POST \
  -H 'Content-Type: image/jpeg' \
  --data-binary "@/path/to/image.jpg" \
  'https://myProjectId.api.sanity.io/v2021-06-07/assets/images/myDataset'

Both methods create the asset document automatically, making the image available in Studio's asset picker.

Browsing uploaded assets

Authors can access these pre-uploaded images through:

  • The built-in image picker in any image field
  • The Sanity Media plugin which provides a dedicated asset browser
  • The Media Library (Enterprise feature) for organization-wide asset management with tagging and metadata

Querying standalone assets

You can also query all uploaded images using GROQ:

*[_type == "sanity.imageAsset"]

So to directly answer your question: No, images don't need to be part of a document to be imported. You can upload them standalone, and they'll be immediately available for your authors to use wherever they need them in their content.

Hm. I'm surprised that this is the first time we had that question. I must admit I’m not sure if it’s possible upload just the images via the CLI, but you could get around it by making an ndjson like this.
{ "_type": "imageImport", "image": { "_type": "image", "_sanityAsset": "image@file:///path/to/image/file.jpg", } }
Import the documents (and the assets), and then run this script to delete all the
imageImport
 files after you're done with
*[_type == "imageImport"]
https://github.com/sanity-io/sanity-recipes/blob/master/snippets/deleteDocsByFilter.js
Hm. I'm surprised that this is the first time we had that question. I must admit I’m not sure if it’s possible upload just the images via the CLI, but you could get around it by making an ndjson like this.
{ "_type": "imageImport", "image": { "_type": "image", "_sanityAsset": "image@file:///path/to/image/file.jpg", } }
Import the documents (and the assets), and then run this script to delete all the
imageImport
 files after you're done with
*[_type == "imageImport"]
https://github.com/sanity-io/sanity-recipes/blob/master/snippets/deleteDocsByFilter.js
I'm surprised too 😅. Thanks Knut I'll give it a try!!
Should I be worried that the export gave a
Unhandled rejection: TypeError: Cannot read property 'setTimeout' of undefined
error and it's been exporting for 10 minutes now 🙂 ?
I'm exporting a very small dataset btw
Not sure what that means. Try running it with
DEBUG=sanity*
prepended to the export(?) command?
Exporting documents...  sanity:export Error, retrying after 1500ms: Cannot read property 'setTimeout' of undefined +146ms
⠹ Exporting documents...  sanity:export Error, retrying after 1500ms: Cannot read property 'setTimeout' of undefined +2s
⠹ Exporting documents...  sanity:export Error, retrying after 1500ms: Cannot read property 'setTimeout' of undefined +2s
⠙ Exporting documents...  sanity:export Error, retrying after 1500ms: Cannot read property 'setTimeout' of undefined +2s
⠹ Exporting documents...  sanity:export Error, retrying after 1500ms: Cannot read property 'setTimeout' of undefined +2s
⠋ Exporting documents...Unhandled rejection: TypeError: Cannot read property 'setTimeout' of undefined
    at /Users/proko/sanity-studio/node_modules/@sanity/export/lib/requestStream.js:73:31
    at Generator.next (<anonymous>)
    at /Users/proko/sanity-studio/node_modules/@sanity/export/lib/requestStream.js:79:10
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (/Users/proko/sanity-studio/node_modules/@sanity/export/lib/requestStream.js:9:103)
    at _next (/Users/proko/sanity-studio/node_modules/@sanity/export/lib/requestStream.js:11:194)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
⠴ Exporting documents...

🤔 is this giving any hints?
Did an upgrade and export again and this time it worked. This is a "my code (works|doesn't work) and have no idea why" situation!!

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?