Skip to main content
Sanity Studio is configured through a sanity.config.ts (or .js) file at the root of your project. The configuration defines your workspace(s), schema, plugins, and various Studio behaviors.

Basic configuration

Use defineConfig() to create your Studio configuration:
import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'

export default defineConfig({
  name: 'default',
  title: 'My Studio',
  
  projectId: 'your-project-id',
  dataset: 'production',
  
  plugins: [
    structureTool(),
  ],
  
  schema: {
    types: [
      // Your schema types
    ],
  },
})

Core configuration options

Project and dataset

Every Studio must specify a project ID and dataset:
export default defineConfig({
  projectId: 'abc123xyz',  // Your project ID from sanity.io/manage
  dataset: 'production',    // Dataset name (e.g., 'production', 'staging')
})

Workspace identity

export default defineConfig({
  name: 'default',           // Internal workspace name (URL-safe)
  title: 'My Content Studio', // Display title in UI
  subtitle: 'Production',     // Optional subtitle
})

Multiple workspaces

You can configure multiple workspaces in a single Studio. Each workspace can connect to different projects or datasets:
import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'

export default defineConfig([
  {
    name: 'production',
    title: 'Production',
    projectId: 'abc123',
    dataset: 'production',
    basePath: '/production',
    plugins: [structureTool()],
    schema: {types: []},
  },
  {
    name: 'staging',
    title: 'Staging',
    projectId: 'abc123',
    dataset: 'staging',
    basePath: '/staging',
    plugins: [structureTool()],
    schema: {types: []},
  },
])
The basePath property sets the URL path for each workspace (e.g., /production, /staging). This is different from the CLI basePath option which sets the root path for the entire Studio.

Schema configuration

Define your content structure using the schema property:
import {defineConfig, defineType, defineField} from 'sanity'

export default defineConfig({
  // ...
  schema: {
    types: [
      defineType({
        name: 'post',
        type: 'document',
        title: 'Blog Post',
        fields: [
          defineField({
            name: 'title',
            type: 'string',
            title: 'Title',
            validation: (Rule) => Rule.required(),
          }),
          defineField({
            name: 'content',
            type: 'array',
            title: 'Content',
            of: [{type: 'block'}],
          }),
        ],
      }),
    ],
  },
})

Plugins

Plugins extend Studio functionality:
import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'
import {visionTool} from '@sanity/vision'
import {colorInput} from '@sanity/color-input'

export default defineConfig({
  // ...
  plugins: [
    structureTool(),
    visionTool(),
    colorInput(),
  ],
})

Plugin configuration

Many plugins accept options:
import {structureTool} from 'sanity/structure'
import {visionTool} from '@sanity/vision'

export default defineConfig({
  plugins: [
    structureTool({
      name: 'content',
      title: 'Content',
      structure: (S) =>
        S.list()
          .title('Content')
          .items([
            S.documentTypeListItem('post').title('Posts'),
            S.documentTypeListItem('author').title('Authors'),
          ]),
    }),
    visionTool({
      defaultApiVersion: '2024-01-01',
      defaultDataset: 'production',
    }),
  ],
})

Document configuration

Configure document-level behaviors:
export default defineConfig({
  // ...
  document: {
    // Enable comments on documents
    comments: {
      enabled: true,
    },
    
    // Customize document actions
    actions: (prev, context) => {
      // Remove unpublish action for certain types
      if (context.schemaType === 'settings') {
        return prev.filter(({action}) => action !== 'unpublish')
      }
      return prev
    },
    
    // Customize document badges
    badges: (prev, context) => {
      // Add custom badge for draft documents
      return prev
    },
  },
})

Form configuration

Customize form behavior and asset sources:
import {unsplashAssetSource} from 'sanity-plugin-asset-source-unsplash'

export default defineConfig({
  // ...
  form: {
    image: {
      assetSources: [unsplashAssetSource],
      directUploads: true,
    },
    file: {
      assetSources: [],
      directUploads: true,
    },
  },
})

Tools configuration

Tools are top-level views in the Studio navigation. You can customize existing tools or add new ones:
export default defineConfig({
  // ...
  tools: (prev, {currentUser}) => {
    // Only show Vision tool to administrators
    const isAdmin = currentUser?.roles.some(
      (role) => role.name === 'administrator'
    )
    
    if (!isAdmin) {
      return prev.filter((tool) => tool.name !== 'vision')
    }
    
    return prev
  },
})

Advanced options

Custom API host

For custom CNAMEs or proxies:
export default defineConfig({
  projectId: 'abc123',
  dataset: 'production',
  apiHost: 'https://api.mycompany.com',
})

Authentication

Configure authentication methods:
export default defineConfig({
  // ...
  auth: {
    loginMethod: 'token',  // or 'dual' (default)
  },
})

Studio components

Customize Studio UI components:
import {MyCustomNavbar} from './components/MyCustomNavbar'

export default defineConfig({
  // ...
  studio: {
    components: {
      navbar: MyCustomNavbar,
    },
  },
})

Error handling

Add custom error handling:
export default defineConfig({
  // ...
  onUncaughtError: (error, errorInfo) => {
    console.error('Studio error:', error)
    // Send to error tracking service
  },
})

Configuration context

Many configuration options receive a context object with useful information:
export default defineConfig({
  // ...
  document: {
    actions: (prev, context) => {
      // context includes:
      // - projectId: string
      // - dataset: string
      // - schema: Schema
      // - currentUser: CurrentUser | null
      // - documentId: string
      // - schemaType: string
      
      console.log('Current user:', context.currentUser)
      return prev
    },
  },
})

Environment-specific configuration

Use environment variables for different environments:
const isProd = process.env.NODE_ENV === 'production'

export default defineConfig({
  projectId: process.env.SANITY_STUDIO_PROJECT_ID!,
  dataset: isProd ? 'production' : 'development',
  
  plugins: [
    structureTool(),
    // Only include Vision in development
    ...(!isProd ? [visionTool()] : []),
  ],
})
You can use sanity.config.ts for TypeScript support and better autocomplete in your configuration.

Type-safe configuration

Leverage TypeScript for type-safe configuration:
import {defineConfig, type WorkspaceOptions} from 'sanity'

const sharedConfig: Partial<WorkspaceOptions> = {
  projectId: 'abc123',
  plugins: [structureTool()],
}

export default defineConfig([
  {
    ...sharedConfig,
    name: 'production',
    title: 'Production',
    dataset: 'production',
    basePath: '/production',
    schema: {types: []},
  },
  {
    ...sharedConfig,
    name: 'staging',
    title: 'Staging',
    dataset: 'staging',
    basePath: '/staging',
    schema: {types: []},
  },
])

Build docs developers (and LLMs) love