Importing block content with images into Sanity and resolving issues.

5 replies
Last updated: Aug 9, 2023
Hey there everyone,
I'm curious if anyone can offer some guidance on importing block content that contains images. I have already used the
@sanity/block-tools
to import the content, but would like all images to also be imported into Sanity as well.
I have already been using the
_sanityAsset
helper elsewhere, but I'm not certain how to format the rules so that Sanity gets the structure correct. Some pointers would be very appreciated!
AI Update

Great question! When importing block content with images using @sanity/block-tools, you'll need to set up your deserialize rules to handle image elements and use the _sanityAsset helper to tell Sanity to fetch and import those images during the import process.

Here's the key pattern that works well:

'rules': [
  {
    deserialize(el, next, block) {
      if (el.tagName?.toLowerCase() === 'img') {
        return block({
          _type: 'image',
          _sanityAsset: `image@${el.src}`,
          nodes: next(el.childNodes),
        })
      }
    }
  }
]

The magic happens with _sanityAsset: 'image@${el.src}' - this tells Sanity's import process to fetch the image from the URL in el.src and create a proper Sanity asset during import.

Complete workflow

Your block content schema should look something like this:

{
  type: 'array',
  name: 'content',
  title: 'Content',
  of: [
    {
      type: 'block',
    },
    {
      type: 'image',
      fields: [
        {
          type: 'string',
          name: 'alt',
          title: 'Alt',
          description: 'The alt text of the image',
        },
      ],
    },
  ],
}

Then when querying the content, you can access the imported images like this:

content[] {
  ...,
  _type == "image" => {
    "src": asset->url,
    alt,
  },
}

Important notes

  • No pre-loading needed: You don't need to upload the images to Sanity beforehand. The _sanityAsset helper fetches and imports them automatically during the import process.

  • URL accessibility: Make sure the image URLs in your source content are publicly accessible when you run the import.

  • NDJSON output: Your import script should output to an NDJSON file, which you then import using the Sanity CLI: sanity dataset import your-file.ndjson production

The _sanityAsset helper works with the format image@<url> for images and file@<url> for other file types, making it straightforward to import various asset types into your Sanity dataset.

After some experimenting, this does the trick:

'rules': [
  {
    deserialize(el, next, block) {
      if (el.tagName?.toLowerCase() === 'img') {
        return block({
          _type: 'image',
          _sanityAsset: `image@${el.src}`,
          nodes: next(el.childNodes),
        })
      }
    }
  }
]
Thanks for sharing your solution!
user S
When you did this, did you load the images to Sanity beforehand?
user S
actually I'm curious of your whole blockContent structure. Really struggling to get images to load.
user S
The schema for the block content is something like this:



{
  type: 'array',
  name: 'content',
  title: 'Content',
  description: 'The content of the blog post.',
  of: [
    {
      type: 'block',
    },
    {
      type: 'image',
      fields: [
        {
          type: 'string',
          name: 'alt',
          title: 'Alt',
          description: 'The alt text of the image',
        },

      ],
    },
  ],
},
The query includes something like this:


content[] {
  ...,
  _type == "image" => {
    "src": asset->url,
    alt,
  },
},
And then the import script basically ran a rule like I pasted in my original post which was deserializing images from source HTML files and replacing them with "sanity images". That would then get output to a ndjson file, and imported using the CLI.

Note that the `_sanityAsset: `image@${el.src}`` line basically tells sanity to load whatever is at
el.src
as an image during the import.
Would be helpful to know if: you're still seeing issues, and if you are, where specifically you're seeing them. ie, importing them? querying them? Displaying them?

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?