Overview
Connect your Sirv account to browse your Sirv DAM (folders, search, thumbnails) and pick images, videos, 360 spins or any file to add to your page.
Your Sirv assets stay on Sirv (you store the path + delivery domain + dimensions) and
render on the frontend with the companion package
@sirv/react. It includes
automatically scaled images to suit each users' device, lazy loading, image zoom, 360 spins,
galleries, GLB models and video streaming.
- No backend required - Sanity Studio talks directly to Sirv's REST API.
- No credentials exposed - REST credentials are encrypted in the dataset's secrets.
- Self-host friendly - designed for a locally-run / self-hosted Studio.
Install
Install the Studio plugin and the companion frontend renderer:
npm install @sirv/sanity-plugin
# to display picked assets on your site
npm install @sirv/react
Peer deps (already in a Studio): sanity, @sanity/ui,
@sanity/icons, react, react-dom,
styled-components.
Configure
Add the plugin in sanity.config.ts - it registers everything automatically.
import { defineConfig } from 'sanity';
import { sirv } from '@sirv/sanity-plugin';
export default defineConfig({
// ...
plugins: [sirv()],
});
Connect your account
- Open the Sirv tool in the Studio's top tool menu (cog icon).
- Paste your account's REST Client ID and Client secret (Sirv → Account → Settings → API).
- Pick a delivery domain (a
*.sirv.comhost or a custom domain). - Done - the connection is saved (encrypted) in the dataset and reused silently. Use Disconnect to switch accounts.
Browse Sirv on image & file fields
Every standard image and file field gains a Browse Sirv
option in its Select menu. Picking imports the file into Sanity. Image fields show
images only; file fields show all types, including generic files (PDF, ZIP).
defineField({ name: 'cover', type: 'image' }); // gets "Browse Sirv"
defineField({ name: 'brochure', type: 'file' }); // any Sirv file (PDF/zip/...)
sirvMedia field (recommended)
A single Sirv-native asset. It stays on Sirv; the field stores its path,
delivery domain, dimensions and optional transformations. Restrict the pickable types with
options.allowedTypes. Auto-fills Alt/Caption from the asset's Sirv metadata.
defineField({
name: 'hero',
type: 'sirvMedia',
options: { allowedTypes: ['image', 'video'] }, // image | video | spin | view
});
sirvMediaList field (gallery)
An ordered list of Sirv-native assets with a persistent add button and multi-select in the browser (tick several, add them together).
defineField({
name: 'gallery',
type: 'sirvMediaList',
options: { allowedTypes: ['image', 'video', 'spin', 'view'] },
});
sirvAssetUrl field
A url field whose value is a picked Sirv asset's delivery URL (any type,
generic files included). Use it when you just need a string URL.
defineField({ name: 'downloadUrl', type: 'sirvAssetUrl' });
Supported asset types
| Type | Extensions | Rendered by @sirv/react as |
|---|---|---|
| Image | jpg, png, webp, avif, gif, ... | <SirvImage> (responsive srcset + lazy) |
| Video | mp4, mov, webm, ... | <SirvVideo> (poster + controls) |
| 360 Spin | .spin | <SirvSpin> (sirv.js) |
| Sirv View | .view | <SirvView> (sirv.js composite) |
| File | pdf, zip, ... | imported into Sanity / plain URL |
Stored value
A sirvMedia value (and each sirvMediaList item):
{
"_type": "sirvMedia",
"mediaType": "image", // image | video | spin | view
"sirvPath": "/products/shoe.jpg",
"sirvAlias": "demo.sirv.com", // chosen delivery domain
"originalUrl": "https://demo.sirv.com/products/shoe.jpg",
"width": 2000, "height": 1500,
"alt": "...", "caption": "...",
"transformations": { "quality": 82 }
}
sirvAssetUrl stores a plain URL string. Image/file Asset Source
fields store standard Sanity asset references.
Render on the frontend
Fetch the fields as-is with GROQ (they are plain objects), then render with
@sirv/react:
import { SirvProvider, SirvMedia, SirvGallery, fromSanityMedia } from '@sirv/react';
<SirvProvider alias="demo.sirv.com" quality={82}>
<SirvMedia value={fromSanityMedia(post.hero)} width={800} />
<SirvGallery items={post.gallery.map(fromSanityMedia)} layout="viewer" />
</SirvProvider>
See the @sirv/react docs for every component and the next/image loader.