Media Library

Folders

Organize Media Library assets into a navigable hierarchy with folders.

Beta primitive

Folder document types

A folder hierarchy in Media Library is made up of three document types from the Content Lake hierarchy primitive: sanity.tree, sanity.directory, and sanity.symlink.

Assets (sanity.asset) sit inside folders by carrying a parent reference to a sanity.directory.

Get started with the API

These examples use @sanity/client configured against your Media Library. They also work through the standard Media Library mutate and query endpoints.

Step 1: Create the tree

Every folder hierarchy starts with one sanity.tree document. In the following code, replace MEDIA_LIBRARY_ID with your library's ID, and set the SANITY_TOKEN environment variable to your personal authentication token.

import {createClient} from '@sanity/client'

const libraryId = 'MEDIA_LIBRARY_ID'

const client = createClient({
  apiVersion: '2025-02-19',
  resource: {type: 'media-library', id: libraryId},
  token: process.env.SANITY_TOKEN,
})

await client.createIfNotExists({
  _id: `tree.${libraryId}`,
  _type: 'sanity.tree',
  name: 'folders',
})

Step 2: Create folders

Create a sanity.directory with a name and a parent reference. Top-level folders point at the tree; nested folders point at their parent directory.

// Use the same `tree.${libraryId}` ID created in Step 1
const treeId = `tree.${libraryId}`

// Top-level folder
const marketing = await client.create({
  _type: 'sanity.directory',
  name: 'Marketing',
  parent: {_ref: treeId},
})

// Nested folder
const campaigns = await client.create({
  _type: 'sanity.directory',
  name: 'Campaigns',
  parent: {_ref: marketing._id},
})

For directory creation patterns, validation rules, and the error reference, see Creating directories in the hierarchy primitive.

Step 3: Place assets in a folder

For assets that are already uploaded, set parent on the sanity.asset document to move it into a folder. In the following code, replace ASSET_ID with the _id of the sanity.asset document.

await client
  .patch('ASSET_ID')
  .set({parent: {_ref: campaigns._id}})
  .commit()

Place assets inside a sanity.directory rather than directly under the tree. The schema permits both, but the Media Library app browses, lists, and operates on assets through directories. Leave parent unset to keep an asset outside of the folder hierarchy.

Upload directly into a folder

When uploading a new asset, set the parent query parameter on the upload endpoint to place it in a folder in a single request, without a follow-up patch.

For the full upload pattern, see Upload assets programmatically.

Query assets and folders

Media Library hierarchy is queried with standard GROQ. The same patterns documented in Querying the hierarchy apply.

You can query assets inside a specific folder with:

*[_type == "sanity.asset" && parent._ref == $folderId]

Move folders and assets

Patch parent to a new destination. The server validates the destination before any change is applied. See the error reference.

// Move Campaigns out of Marketing to the top level
await client
  .patch(campaigns._id)
  .set({parent: {_ref: treeId}})
  .commit()

The same pattern applies to assets. Set parent to move an asset into a different folder, or unset it to take the asset out of its folder. Shortcuts that target the asset remain until you delete them.

Shortcuts

A shortcut makes a single asset visible inside an additional folder without duplicating the underlying file. Shortcuts are sanity.symlink documents that reference a destination folder using parent and an asset using target.

await client.create({
  _type: 'sanity.symlink',
  parent: {_ref: marketing._id},
  target: {_ref: 'ASSET_ID'},
})

Media Library constraint

Delete folders

Delete a folder with the standard delete mutation. In the following code, replace FOLDER_ID with the _id of the sanity.directory document:

await client.delete('FOLDER_ID')

No cascade delete

In the Media Library app, the Delete folder action handles this for you. It deletes children recursively and displays a confirmation dialog that surfaces information about contents and potential warnings. If an asset inside the folder is in use by a document in one of your studios, the app blocks the deletion until you remove those references. See Deleting folders in the interface.

Was this page helpful?

Sanity logosanity.ioAll Systems Operational© Sanity 2026
Change site theme