How to Integrate Transloadit with Your Headless CMS
Send newly published media from your headless CMS to Transloadit for resizing, encoding, watermarking, and delivery without editors re-uploading files by hand.
What is Transloadit?
Transloadit is a file processing platform for developers that handles uploads, imports, exports, and media processing through an API. Teams use it to resize images, encode video, extract thumbnails, scan files, add watermarks, convert documents, and move processed files into services like Amazon S3, Google Cloud Storage, or Azure Blob Storage. Its workflow model is built around Assemblies, which run ordered processing steps called Robots.
Why integrate Transloadit with a headless CMS?
Media work gets messy when content and file processing live in separate places. An editor publishes a product page with a 4K demo video, but someone still has to upload that video to a processing tool, wait for HLS renditions, copy the final URLs, and paste them back into the entry. Multiply that by 50 product pages, 12 locales, and weekly campaign updates, and you’ve got a slow, error-prone workflow.
Connecting Transloadit to a headless CMS category tool solves that by letting the publishing event start the media pipeline. When an editor publishes content, your integration can send the asset URL and metadata to Transloadit, run a specific Assembly Template, store the outputs in your media bucket, and write the resulting URLs back to the content entry. With Sanity, structured content in the Content Lake means you can query exactly the media fields Transloadit needs. Webhooks or Functions can trigger the job the moment content changes.
The trade-off is that you’ll need to design the handoff carefully. Large private files need signed URLs or another secure import strategy, and long-running Transloadit jobs usually need a callback to update content after processing finishes. That’s still better than asking editors to track variants, thumbnails, captions, and encoding status in spreadsheets.
Architecture overview
A typical Sanity and Transloadit integration starts when an editor publishes a document that references a video, image, audio file, or document asset in the Content Lake. A Sanity webhook fires on the publish event and sends the document ID to a webhook listener, or a Sanity Function runs the same server-side logic without separate infrastructure. The handler uses GROQ to fetch only the fields needed for processing, such as the asset URL, title, alt text, locale, destination folder, and any referenced campaign or product data. It then calls Transloadit’s Node SDK or HTTP API to create an Assembly. The Assembly can import the Sanity asset URL with the /http/import Robot, process it with Robots like /image/resize, /video/encode, /video/thumbs, /audio/encode, or /file/viruscheck, and export the results with /s3/store or another storage Robot. After Transloadit completes the job, it can call a notify_url endpoint. That callback can patch the Sanity document with the Assembly ID, processing status, thumbnail URL, HLS playlist URL, file size, duration, or rendition metadata. From there, your frontend queries Sanity for the ready-to-render media fields and serves the processed assets to web, mobile, ecommerce, or app experiences.
Common use cases
Video renditions on publish
Publish a Sanity video entry and have Transloadit create HLS output, MP4 fallbacks, poster frames, and duration metadata.
Campaign image variants
Generate square, landscape, portrait, and retina image sizes from one source asset when campaign content goes live.
File checks before distribution
Send uploaded PDFs, ZIP files, or user-submitted media through Transloadit virus scanning before exposing download links.
Localized media workflows
Use Sanity locale fields to route region-specific assets into different Transloadit export paths, buckets, or watermarked variants.
Step-by-step integration
- 1
Create your Transloadit account and credentials
Create a Transloadit account, copy your Auth Key and Auth Secret from the dashboard, and decide whether you’ll use inline Assembly steps or an Assembly Template. For repeatable workflows, create a template with Robots such as /http/import, /image/resize, /video/encode, /video/thumbs, and /s3/store.
- 2
Install the SDKs
In your webhook service, Sanity Function, or middleware app, install the packages you need: transloadit for creating Assemblies and @sanity/client for fetching structured content with GROQ.
- 3
Model media fields in Sanity Studio
Add typed fields for the source asset, processing status, Assembly ID, output URLs, thumbnails, duration, alt text, and any routing metadata. For example, a video document might include sourceFile, transloaditStatus, hlsUrl, posterUrl, and durationSeconds.
- 4
Create the publish trigger
Add a Sanity webhook filtered to the media documents you want to process, such as _type == "video" && defined(sourceFile). Use a projection that sends the document ID. If you want the logic to run inside Sanity’s event system, use a Sanity Function instead of hosting your own listener.
- 5
Call Transloadit and save the job state
When the webhook fires, fetch the full document with GROQ, create a Transloadit Assembly, and patch the Sanity document with the Assembly ID and a processing status. Configure Transloadit notify_url so a completion callback can write final output URLs back to Sanity.
- 6
Test the frontend experience
Publish one test asset, confirm that Transloadit creates the expected outputs, and query Sanity from your frontend for the processed URLs. Show a processing state if transloaditStatus is pending, and render the final image, video, or download link when complete.
Code example
import express from 'express'
import Transloadit from 'transloadit'
import {createClient} from '@sanity/client'
const app = express()
app.use(express.json())
const sanity = createClient({
projectId: process.env.SANITY_PROJECT_ID!,
dataset: process.env.SANITY_DATASET!,
apiVersion: '2025-01-01',
token: process.env.SANITY_WRITE_TOKEN!,
useCdn: false
})
const transloadit = new Transloadit({
authKey: process.env.TRANSLOADIT_AUTH_KEY!,
authSecret: process.env.TRANSLOADIT_AUTH_SECRET!
})
app.post('/webhooks/sanity/transloadit', async (req, res) => {
const id = req.body._id
const video = await sanity.fetch(`*[_id == $id][0]{
_id,
title,
"assetUrl": sourceFile.asset->url
}`, {id})
if (!video?.assetUrl) return res.status(204).end()
const assembly = await transloadit.createAssembly({
params: {
notify_url: process.env.TRANSLOADIT_NOTIFY_URL,
steps: {
import: {robot: '/http/import', url: video.assetUrl},
hls: {use: 'import', robot: '/video/encode', preset: 'hls'},
poster: {use: 'import', robot: '/video/thumbs', count: 1},
export: {
use: ['hls', 'poster'],
robot: '/s3/store',
credentials: 'aws-prod',
path: 'sanity/' + video._id + '/${file.url_name}'
}
}
},
fields: {sanityId: video._id, title: video.title}
})
await sanity.patch(video._id).set({
transloaditStatus: 'processing',
transloaditAssemblyId: assembly.assembly_id
}).commit()
res.json({assemblyId: assembly.assembly_id})
})
app.listen(3000)How Sanity + Transloadit works
Build your Transloadit integration on Sanity
Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect publishing workflows with Transloadit media processing.
Start building free →CMS approaches to Transloadit
| Capability | Traditional CMS | Sanity |
|---|---|---|
| Media data shape | Media is often tied to pages, plugins, or editor fields, so custom processing may require parsing rendered content or plugin-specific tables. | The Content Lake stores typed JSON, so Transloadit can receive exact asset URLs, metadata, references, and routing fields from one GROQ query. |
| Processing trigger | Processing commonly depends on upload hooks, scheduled jobs, or plugin behavior that may not match publish timing. | Webhooks can filter publish events with GROQ, and Functions can run server-side processing logic without a separate worker service. |
| Field-level control | The integration may receive too much page data or not enough linked metadata, especially for reused assets. | GROQ can fetch the media asset, parent content, brand settings, locale, and destination path in one request. |
| Writing results back | Saving HLS URLs, thumbnails, and processing status often needs custom plugin fields or database changes. | Your schema can include processing status, Assembly IDs, output URLs, and editor-facing previews directly in Sanity Studio. |
| Multi-channel delivery | Processed media is usually tied first to the website, with extra work needed for apps, kiosks, or AI agents. | One structured back end can feed web, mobile, Transloadit workflows, and production AI agents through Agent Context. |
Keep building
Explore related integrations to complete your content stack.
Sanity + Cloudinary
Connect structured Sanity content with Cloudinary for image and video transformations, delivery, and asset metadata.
Sanity + Mux
Publish video content in Sanity and use Mux for streaming, thumbnails, playback IDs, and viewing analytics.
Sanity + Bynder
Reference approved Bynder brand assets from Sanity entries while keeping campaign, product, and channel content structured.