ZONILY_JAME Work with me?

ARTICLE // ON_SITE

Keeping a Media-Heavy Site Fast: Why Sanity Needs Cloudinary

How I offloaded high-fidelity media to Cloudinary to solve performance bottlenecks on the Smitten website.

Published
Read
5 MIN
Author
Zonily Jame
  • #CMS
  • #Performance
  • #Cloudinary
  • #Sanity
  • #Optimization

The Smitten website uses large background videos and high-resolution images. They look good, but some of the original video files were more than 10MB. Sending the same file to every device would have been a waste, especially on mobile.

Sanity already managed the website content. I could have stored every image and video there as well, but video processing is not what I needed Sanity to do.

So I used Sanity for the content and Cloudinary for the heavier files.

Why use both?

Sanity works well for regular marketing images. The trouble started with the hero videos. I needed WebM and MP4 files, different sizes for different screens, and a way to avoid sending a desktop video to a phone.

Cloudinary already handles those transformations. Sanity did not need to become a video pipeline just because it was the CMS.

I added a flexibleMedia object to the Sanity schema. An editor can upload a Sanity image, select a Cloudinary asset, or use a local path.

// sanity/schemas/objects/flexibleMedia.ts
export default {
  name: 'flexibleMedia',
  title: 'Flexible Media',
  type: 'object',
  fields: [
    {
      name: 'sources',
      type: 'array',
      of: [
        { type: 'image', title: 'Sanity Asset', options: { hotspot: true } },
        { type: 'cloudinary.asset', title: 'Cloudinary Asset' },
        { type: 'string', name: 'localPath', title: 'Local Path' }
      ]
    },
    {
      name: 'alt',
      type: 'string',
      title: 'Alt Text',
      validation: Rule => Rule.required()
    }
  ]
}

On the frontend, a custom hook checks the available sources. If the entry has a Cloudinary asset, the site requests it with f_auto,q_auto. Otherwise, it uses the Sanity image builder.

What changed

The 10MB hero video moved to Cloudinary. A phone could then receive a 720p version instead of downloading the 4K desktop file.

That reduced the average asset payload by almost 50% and improved Largest Contentful Paint. Editors did not need to learn another publishing workflow either. They still worked in Sanity, and the frontend decided how to load the asset.

One annoying detail

Cloudinary and Sanity each support asset metadata. If an editor changed the alt text in Cloudinary, Sanity would not know about it. Keeping both copies in sync would become annoying fast.

I made Sanity the only place for that metadata. The file can live in Cloudinary, but the frontend reads its alt text from the Sanity object.

The setup is not clever, and that is the point. Sanity stores the content. Cloudinary processes the large media. Each tool does the job I picked it for.


Written by

Zonily Jame

About me

[01]COMMENTS

Discussion

Questions, corrections or war stories. Sign in with GitHub to join in.

Loading comments…

All articles

[ READY_TO_BUILD? ]

Let's Build Something Great

Start with a 30-minute discovery call to assess if we're a good fit. No commitment, just clarity.

or write to hello@zonilyjame.dev