Attaching images to Sanity editor using generated blobs

5 replies
Last updated: Oct 8, 2020
Hello folks, I'm wondering if it's possible to attach on the editor a blob as an actual image?What I'm thinking of is...

1. On the editor, I put a title and a description
2. There is a button called "Generate og:image"
3. If I click it, it creates a blob of image on the browser
4. It is attached as an actual image
5. It will be uploaded to sanity cdn.
6. During the build time (or on the server) the url is used for 'og:image' tag.

I'm curious about (4). I might need to dig more into sources of image type. But has anyone done something similar already?

https://www.sanity.io/docs/image-type#sources-d82cf03b063c
AI Update

Yes, this is absolutely possible! You can generate an image in the browser (like an og:image), convert it to a blob, and upload it directly to Sanity's CDN using the client.assets.upload() method.

Here's how to accomplish what you're describing:

Uploading a browser-generated blob to Sanity

import {createClient} from '@sanity/client'

const client = createClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset',
  token: process.env.SANITY_WRITE_TOKEN, // You'll need a write token
  apiVersion: '2025-02-06',
  useCdn: false
})

// 1. Generate your og:image (example using canvas)
async function generateOgImage(title, description) {
  const canvas = document.createElement('canvas')
  canvas.width = 1200
  canvas.height = 630
  const ctx = canvas.getContext('2d')
  
  // Draw your og:image content
  ctx.fillStyle = '#000'
  ctx.fillRect(0, 0, 1200, 630)
  ctx.fillStyle = '#fff'
  ctx.font = '48px sans-serif'
  ctx.fillText(title, 50, 100)
  
  // 3. Convert canvas to blob
  return new Promise(resolve => {
    canvas.toBlob(resolve, 'image/png')
  })
}

// 4. Upload blob to Sanity
async function uploadOgImage(blob, documentId) {
  const asset = await client.assets.upload('image', blob, {
    filename: `og-image-${documentId}.png`,
    contentType: 'image/png'
  })
  
  // 5. Attach to your document
  await client
    .patch(documentId)
    .set({
      ogImage: {
        _type: 'image',
        asset: {
          _type: 'reference',
          _ref: asset._id
        }
      }
    })
    .commit()
    
  return asset
}

// Put it all together
async function handleGenerateOgImage(documentId, title, description) {
  const blob = await generateOgImage(title, description)
  const asset = await uploadOgImage(blob, documentId)
  
  // 6. Use the URL in your og:image tag
  const imageUrl = asset.url
  console.log('og:image URL:', imageUrl)
  return imageUrl
}

Using with Custom Asset Sources

Since you mentioned looking at custom asset sources, you could also create a custom asset source plugin that integrates this generation directly into your Studio's image field. This would give your editors a "Generate og:image" button right in the image input.

Here's a simplified example of a custom asset source:

// customOgImageSource.js
export default {
  name: 'og-image-generator',
  title: 'Generate OG Image',
  component: OgImageGenerator,
  icon: () => '🎨'
}

function OgImageGenerator({onSelect, document}) {
  const handleGenerate = async () => {
    const blob = await generateOgImage(document.title, document.description)
    
    // Upload using the client
    const asset = await client.assets.upload('image', blob, {
      filename: `og-${document._id}.png`
    })
    
    // Return to the image field
    onSelect([{
      kind: 'assetDocumentId',
      value: asset._id
    }])
  }
  
  return <button onClick={handleGenerate}>Generate OG Image</button>
}

Then configure it in your schema:

{
  name: 'ogImage',
  type: 'image',
  options: {
    sources: [
      {name: 'og-image-generator', title: 'Generate', component: OgImageGenerator}
    ]
  }
}

Key Points

  • The client.assets.upload() method accepts blobs directly in the browser
  • You need a write token to upload assets
  • The uploaded asset gets a permanent URL on Sanity's CDN that you can use in your og:image meta tags
  • The asset is stored as a proper Sanity asset document and can be referenced from your content documents

This approach gives you a fully automated og:image generation workflow that stores the images properly in Sanity's asset system!

Oh awesome. I'll watch it now. Thanks 😊
Exactly what I was looking for πŸ‘
user S
let me know if that helps. I need to create some offciial docmumentation around this
Hey it helped a lot! Inspired by you, I'm having a slightly different approach. I'm hosting sanity studio on vercel and created an api which generates image using puppeteer and set the image to the document using sanity client πŸ™‚
So the frontend of the studio just calls the api with
id, title, description
.

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?