How to Integrate Imgix with Your Headless CMS
When one image has to fit product cards, blog headers, mobile screens, and retina displays, connecting Imgix to a headless CMS gives you responsive image delivery from the same structured content.
What is Imgix?
Imgix is an image processing and delivery platform that serves images through URL parameters for resizing, cropping, format conversion, compression, and cache control. Teams use it to deliver fast visual experiences across ecommerce, publishing, marketplaces, and SaaS products without manually exporting separate image variants. It sits between your image source, such as a web folder, S3 bucket, Google Cloud Storage bucket, or asset CDN, and the end user.
Why integrate Imgix with a headless CMS?
A headless CMS setup works well for Imgix when image fields are structured instead of buried inside rendered HTML. With Sanity's AI Content Operating System, image references, hotspot data, captions, product relationships, and publish state live as typed JSON in the Content Lake. GROQ can select only the fields Imgix needs, and webhooks can fire when an article, product, or landing page is published. That means your frontend can build Imgix URLs from predictable fields instead of scraping image tags from a page body.
Architecture overview
A typical Sanity and Imgix setup starts with an Imgix Source pointed at the Sanity asset CDN path for your project and dataset, for example https://cdn.sanity.io/images/<projectId>/production. Editors add images, crops, alt text, and references in Sanity Studio. Those values are written as typed JSON into the Content Lake, including the Sanity asset URL and any editorial metadata your frontend needs.
Common use cases
Product image variants
Generate product grid, PDP, cart, and email image sizes from one Sanity image reference using Imgix width, height, fit, and format parameters.
Editorial hero crops
Use Sanity image hotspot and crop fields to guide Imgix crops for article cards, social previews, and full-width story headers.
Responsive mobile delivery
Serve smaller WebP or AVIF images to mobile layouts while keeping the same source image, alt text, and caption in the Content Lake.
Publish-time cache refresh
Trigger Imgix purge calls when a referenced image changes so cached derivatives update after a Sanity publish event.
Step-by-step integration
- 1
Create your Imgix Source
In Imgix, create a Source that points to your image origin. For Sanity assets, use a Web Folder Source with a base URL like https://cdn.sanity.io/images/<projectId>/<dataset>. Copy your Imgix domain, such as example.imgix.net, and create an API key with purge access if you'll refresh cached images on publish.
- 2
Install the SDKs
In your integration service or Sanity Function project, install @sanity/client and @imgix/js-core. You'll use @sanity/client to fetch structured image fields with GROQ and @imgix/js-core to build Imgix URLs that match your source path.
- 3
Model images in Sanity Studio
Add image fields with alt text, captions, and hotspot support. For example, an article schema might include heroImage, heroImage.alt, heroImage.caption, and body images. Keep image metadata as fields, not as text pasted into rich text, so Imgix and your frontend can consume it directly.
- 4
Create the sync trigger
Use a Sanity webhook or Function that runs on publish events for documents that contain images, such as article, product, or landingPage. Configure the payload to include the document ID, then fetch the full document inside the handler so you're working with current published data.
- 5
Call Imgix from server-side code
Use GROQ to select image asset URLs and metadata, convert each Sanity CDN URL into the path expected by your Imgix Source, and call Imgix's Purge API for changed originals. If you precompute URLs, generate them with @imgix/js-core and write them to your app cache or search index.
- 6
Test the frontend experience
Render images with srcset values like 320, 640, 960, and 1280 widths, then test in Chrome DevTools on slow 4G and high-DPR screens. Confirm that alt text comes from Sanity, Imgix returns the expected format, and a republished image refreshes after the purge call.
Code example
import {createClient} from '@sanity/client'
import ImgixClient from '@imgix/js-core'
import type {Request, Response} from 'express'
const sanity = createClient({
projectId: process.env.SANITY_PROJECT_ID!,
dataset: process.env.SANITY_DATASET!,
apiVersion: '2025-01-01',
token: process.env.SANITY_READ_TOKEN!,
useCdn: false
})
const imgix = new ImgixClient({domain: process.env.IMGIX_DOMAIN!})
const sourceBasePath = `/images/${process.env.SANITY_PROJECT_ID}/${process.env.SANITY_DATASET}`
export async function handleSanityPublish(req: Request, res: Response) {
const id = req.body._id
const doc = await sanity.fetch(`*[_id == $id][0]{
title,
heroImage{alt, asset->{url}},
gallery[]{asset->{url}}
}`, {id})
const urls = [doc?.heroImage?.asset?.url, ...(doc?.gallery || []).map((img: any) => img?.asset?.url)].filter(Boolean)
for (const url of urls) {
const path = new URL(url).pathname.replace(sourceBasePath, '')
const imgixUrl = imgix.buildURL(path, {w: 1200, auto: 'format', q: 75})
await fetch('https://api.imgix.com/api/v1/purge', {
method: 'POST',
headers: {
'Authorization': `Basic ${Buffer.from(`${process.env.IMGIX_API_KEY}:`).toString('base64')}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({url: imgixUrl})
})
}
res.status(200).json({purged: urls.length})
}How Sanity + Imgix works
Build your Imgix integration on Sanity
Sanity gives you the structured content foundation, real-time event system, GROQ queries, and flexible APIs you need to connect Imgix to the content workflows your team already uses.
Start building free →CMS approaches to Imgix
| Capability | Traditional CMS | Sanity |
|---|---|---|
| Image metadata structure | Image data often sits inside page fields or rendered HTML, so downstream tools need parsing rules. | Image references, alt text, captions, crops, hotspots, and relationships are modeled as typed JSON in the Content Lake. |
| Publish-time Imgix updates | Cache refreshes often depend on manual purge buttons, plugins, or scheduled jobs. | Webhooks and Functions can call the Imgix Purge API when relevant documents publish, update, or delete. |
| Field-level control for image sync | Integrations may receive full page payloads, including fields that Imgix doesn't need. | GROQ can fetch exactly the image URLs, alt text, dimensions, products, authors, and references needed in one query. |
| Editorial control over responsive images | Editors may upload separate desktop, mobile, and social images to control crops. | Editors can set hotspot and crop data in Sanity Studio, then frontend code maps those decisions to Imgix parameters. |
| Multi-channel media delivery | Media workflows are often tied to one website template or publishing surface. | The same structured image data can feed websites, mobile apps, Imgix URLs, internal tools, and AI agents. |
Keep building
Explore related integrations to complete your content stack.
Sanity + Cloudinary
Connect structured Sanity content with Cloudinary for image and video asset workflows, transformations, and delivery.
Sanity + Mux
Pair Sanity with Mux to model video metadata, trigger encoding workflows, and publish playback-ready video across channels.
Sanity + Bynder
Use Bynder as a brand asset source while Sanity structures the content, references, and channel-specific context around those assets.