> ## Documentation Index
> Fetch the complete documentation index at: https://autorender.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sanity

> Browse, upload, and pick Autorender assets directly from Sanity Studio — as a source for image and file fields, or as a dedicated schema type that keeps Autorender metadata on your documents.

<Warning>
  **Key type:** browsing your files requires a **private key** (see [Create an API Key](/docs/create-an-api-key)) — but Sanity Studio is a client-side app, so that key ships inside the Studio's JavaScript bundle. Anyone with access to your Studio, including via browser devtools, can read it. Restrict who has access to your Studio deployment accordingly, and treat the key as you would any other client-exposed credential.
</Warning>

The `@autorender/sanity` plugin lets content editors browse, upload, and pick Autorender assets (images, video, and other files) directly from Sanity Studio, without leaving the editor.

## How does it work?

The package ships two plugins you can use independently or together:

1. **`autorenderAssetSourcePlugin`** — adds an "Autorender" entry to the asset picker on standard `image` and `file` fields, alongside Sanity's own "Upload" and "Browse". Picking an asset hands Sanity a plain CDN URL, which Sanity downloads into its own asset pipeline like any other third-party source.
2. **`autorenderSchemaPlugin`** — adds an `autorender.asset` object schema type you attach to your own document schemas. Unlike the asset source above, this keeps serving the file from the Autorender CDN instead of copying it into Sanity, and keeps the asset's Autorender metadata (folder, tags, dimensions, custom metadata) attached to the document for use in GROQ queries.

Both plugins only call your own Autorender workspace's endpoints (list files, list folders, upload) — neither renames nor deletes anything in your workspace.

## Prerequisites

* A Sanity Studio project (**v3 or later**) running locally
* Node.js and npm, yarn, or pnpm
* An Autorender workspace and a private API key — see [Create an API Key](/docs/create-an-api-key)

***

## 1. Install the plugin

<CodeGroup>
  ```bash npm theme={null}
  npm install @autorender/sanity
  ```

  ```bash yarn theme={null}
  yarn add @autorender/sanity
  ```

  ```bash pnpm theme={null}
  pnpm add @autorender/sanity
  ```

  ```bash bun theme={null}
  bun add @autorender/sanity
  ```
</CodeGroup>

***

## 2. Add it to your Studio config

```ts sanity.config.ts {9,10} theme={null}
import {defineConfig} from 'sanity'
import {autorenderAssetSourcePlugin, autorenderSchemaPlugin} from '@autorender/sanity'

const autorenderConfig = {apiKey: process.env.SANITY_STUDIO_AUTORENDER_API_KEY!}

export default defineConfig({
  // ...
  plugins: [
    autorenderAssetSourcePlugin(autorenderConfig),
    autorenderSchemaPlugin(autorenderConfig),
  ],
})
```

Sanity Studio only exposes environment variables prefixed with `SANITY_STUDIO_` to client code, so set your key as `SANITY_STUDIO_AUTORENDER_API_KEY` (or similar) in your Studio's `.env` file.

That's enough to browse, upload, and pick Autorender assets from any `image`/`file` field. The rest of this guide covers the `autorender.asset` schema type and the remaining configuration options.

***

## 3. Use Autorender as an asset source

With `autorenderAssetSourcePlugin` installed, open any `image` or `file` field in the Studio and click **Select**. An "Autorender" entry appears alongside "Upload" and "Browse".

<Frame caption="The Autorender entry in a standard image field's asset source menu.">
  <img src="https://assets.autorender.io/LOKVTtKVGb/doc1/sanity-autorender-select.png" alt="Autorender entry in Sanity's asset source picker" />
</Frame>

Clicking it opens the Autorender browser: search or navigate folders, select a file, and Sanity downloads it into its own asset pipeline.

<Frame caption="Browsing and searching Autorender folders and files from inside Sanity Studio.">
  <img src="https://assets.autorender.io/LOKVTtKVGb/doc1/sanity_editor.png" alt="Autorender file browser dialog inside Sanity Studio" />
</Frame>

***

## 4. Use the `autorender.asset` schema type (optional)

Use this when you want documents to keep serving assets from the Autorender CDN — instead of Sanity's own asset pipeline — with the asset's Autorender metadata available in GROQ queries.

```ts sanity.config.ts theme={null}
import {defineConfig} from 'sanity'
import {autorenderSchemaPlugin} from '@autorender/sanity'
import {schemaTypes} from './schemas'

export default defineConfig({
  // ...
  plugins: [
    autorenderSchemaPlugin({
      apiKey: process.env.SANITY_STUDIO_AUTORENDER_API_KEY!,
    }),
  ],
  schema: {
    types: schemaTypes,
  },
})
```

Then reference `autorender.asset` from your own document schemas:

```ts schemas/post.ts theme={null}
import {defineType} from 'sanity'

export default defineType({
  name: 'post',
  type: 'document',
  fields: [
    {name: 'title', type: 'string'},
    {name: 'coverAsset', type: 'autorender.asset', title: 'Cover'},
    {
      name: 'gallery',
      type: 'array',
      title: 'Gallery',
      of: [{type: 'autorender.asset'}],
    },
  ],
})
```

A single `autorender.asset` field renders a preview with **Select…** / **Remove** buttons. An array of `autorender.asset` gets an extra **Add multiple** button, so editors can pick several assets from one browsing session.

<Frame caption="An autorender.asset field with a selected video, shown by its thumbnail and the Autorender badge.">
  <img src="https://assets.autorender.io/LOKVTtKVGb/doc1/sanity-autorender-upload.png" alt="autorender.asset field showing a selected asset preview" />
</Frame>

Query the asset's fields directly in GROQ — no joins or dereferencing needed, since the data lives on the document itself:

```groq theme={null}
*[_type == "post"]{
  title,
  "cover": coverAsset{
    url,
    thumbnail,
    "alt": metadata.alt_text
  }
}
```

***

## 5. Upload new files

Both the asset-source dialog and the `autorender.asset` field's browser include an **Upload new** button, so editors can add a file straight to Autorender without leaving Sanity. Uploads go to whichever Autorender folder is currently open in the dialog, and the newly uploaded file is selected immediately.

***

## 6. Render the images on your frontend

Rendering differs by field type, since a standard `image` field only stores a *reference* to a Sanity-hosted asset, while an `autorender.asset` field stores the Autorender CDN URL directly on the document.

### The standard `image` field

Resolve the reference into a URL with [`@sanity/image-url`](https://www.npmjs.com/package/@sanity/image-url) — the same package you'd use for any Sanity image, since by this point it's a normal Sanity asset:

<CodeGroup>
  ```bash npm theme={null}
  npm install @sanity/image-url
  ```

  ```bash yarn theme={null}
  yarn add @sanity/image-url
  ```

  ```bash pnpm theme={null}
  pnpm add @sanity/image-url
  ```

  ```bash bun theme={null}
  bun add @sanity/image-url
  ```
</CodeGroup>

```ts lib/sanity.ts theme={null}
import {createClient} from '@sanity/client'
import {createImageUrlBuilder, type SanityImageSource} from '@sanity/image-url'

export const client = createClient({
  projectId: 'your-project-id',
  dataset: 'production',
  apiVersion: '2024-01-01',
  useCdn: true,
})

const imageBuilder = createImageUrlBuilder(client)
export function urlFor(source: SanityImageSource) {
  return imageBuilder.image(source)
}
```

```tsx app/page.tsx theme={null}
import Image from 'next/image'
import {client, urlFor} from '../lib/sanity'

interface Post {
  _id: string
  title: string
  image?: Parameters<typeof urlFor>[0]
}

export default async function Page() {
  const posts = await client.fetch<Post[]>(`*[_type == "post"]{_id, title, image}`)

  return posts.map((post) => (
    <article key={post._id}>
      <h1>{post.title}</h1>
      {post.image && (
        <Image src={urlFor(post.image).width(1200).url()} alt={post.title} width={1200} height={675} />
      )}
    </article>
  ))
}
```

If you're using `next/image`, add Sanity's CDN to your allowed remote patterns:

```js next.config.js theme={null}
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [{protocol: 'https', hostname: 'cdn.sanity.io'}],
  },
}

module.exports = nextConfig
```

### The `autorender.asset` field

No image-builder needed — `url`/`thumbnail` are already plain, permanent CDN links, so query and render them directly:

```groq theme={null}
*[_type == "post"]{
  _id,
  title,
  coverAsset{fileNo, name, url, thumbnail, width, height, mimeType}
}
```

```tsx app/page.tsx theme={null}
import Image from 'next/image'
import {client} from '../lib/sanity'

interface AutorenderAsset {
  name: string
  url: string
  width: number | null
  height: number | null
}

interface Post {
  _id: string
  title: string
  coverAsset?: AutorenderAsset
}

export default async function Page() {
  const posts = await client.fetch<Post[]>(
    `*[_type == "post"]{_id, title, coverAsset{name, url, width, height}}`,
  )

  return posts.map((post) => (
    <article key={post._id}>
      <h1>{post.title}</h1>
      {post.coverAsset && (
        <Image
          src={post.coverAsset.url}
          alt={post.coverAsset.name}
          width={post.coverAsset.width || 1200}
          height={post.coverAsset.height || 675}
        />
      )}
    </article>
  ))
}
```

Add Autorender's CDN to `next.config.js` too, alongside Sanity's:

```js next.config.js theme={null}
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {protocol: 'https', hostname: 'assets.autorender.io'},
      {protocol: 'https', hostname: 'cdn.sanity.io'},
    ],
  },
}

module.exports = nextConfig
```

***

## Advanced: custom base URL

If your Autorender workspace is served from a different API host, pass `baseUrl` alongside `apiKey`:

```ts theme={null}
autorenderSchemaPlugin({
  apiKey: process.env.SANITY_STUDIO_AUTORENDER_API_KEY!,
  baseUrl: 'https://upload.example.com/api/v1',
})
```

## Next steps

<CardGroup cols={2}>
  <Card title="Automatic format" icon="wand-magic-sparkles" iconType="solid" href="/docs/optimization/automatic">
    Serve AVIF or WebP per browser with `f_auto` on the CDN URLs these plugins insert.
  </Card>

  <Card title="Resize and aspect ratio" icon="crop-simple" iconType="solid" href="/docs/transformations/resize-and-aspect-ratio">
    Control width, height, and fit on every delivery URL.
  </Card>
</CardGroup>
