@sirv/sanity-plugin

Sirv as a first-class media source inside Sanity Studio (v3 / v4 / v5).

v0.1.1

Overview

Editors connect their Sirv account, then browse the Sirv DAM (folders, search, thumbnails, live previews) and pick images, videos, 360 spins, Sirv views, or any file - straight from Studio fields. Sirv-native assets stay on Sirv and render on the frontend with @sirv/react.

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

  1. Open the Sirv tool in the Studio's top tool menu (cog icon).
  2. Paste your account's REST Client ID and Client secret (Sirv → Account → Settings → API).
  3. Pick a delivery domain (a *.sirv.com host or a custom domain).
  4. Done - the connection is saved (encrypted) in the dataset and reused silently. Use Disconnect to switch accounts.
Use a private dataset. The connection is stored as a dataset document; a private dataset keeps it from being publicly readable. Credentials are never bundled into the Studio JavaScript, and the plugin ships none of its own.

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

TypeExtensionsRendered by @sirv/react as
Imagejpg, png, webp, avif, gif, ...<SirvImage> (responsive srcset + lazy)
Videomp4, mov, webm, ...<SirvVideo> (poster + controls)
360 Spin.spin<SirvSpin> (sirv.js)
Sirv View.view<SirvView> (sirv.js composite)
Filepdf, 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.