Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

Migrating tools

Custom tools in v2 were extended from the part:@sanity/base/tool part:

// sanity.json
{
  "root": true,
  "project": {
    "name": "My Project"
  },
  // ...
  "parts": [
    {
      "implements": "part:@sanity/base/tool",
      "path": "./tools/myTool"
    },
    // you could implement the part more than once
    {
      "implements": "part:@sanity/base/tool",
      "path": "./tools/myOtherTool"
    }
  ]
}

import React from 'react'

function MyTool() {
  return <>{my tool}</>
}

// ./tools/myTool
export default {
  title: 'My Tool',
  name: 'my-tool',
  component: MyTool,
}

In Studio v3, using the new Config API you declare your custom tools on the root property tools on the configuration object:

// sanity.config.ts
import {defineConfig} from 'sanity'
import MyTool from './MyTool'
import MyOtherTool from './MyOtherTool'

export default defineConfig({
  name: 'default',
  title: 'My Cool Project',
  projectId: 'my-project-id',
  dataset: 'production',
  tools: [
    {name: 'my-tool', title: 'My Tool', component: MyTool},
    {name: 'tool-2', title: '2nd Tool', component: MyOtherTool},
  ],
})

// sanity.config.ts
import {defineConfig} from 'sanity'
import MyAdminTool from './MyAdminTool'

export default defineConfig({
  name: 'default',
  title: 'My Cool Project',
  projectId: 'my-project-id',
  dataset: 'production',
  // could also utilize the function variant for conditionals 😎
  tools: (prev, {currentUser}) => {
    if (currentUser.roles.find((r) => r.name === 'admin')) {
      return [
				...prev,
				{name: 'admin', title: 'Admin', component: MyAdminTool},
			]
    }

		return prev
  },
})

Feedback or questions?

These guides are under development. If you have questions or suggestions for improvement, then we want to hear from you. Get in touch via our GitHub discussions page.

Was this article helpful?