Issue with Sanity/Vision plugin and error message

3 replies
Last updated: May 8, 2023
Im having some issues with the sanity/vision plugin. Today it started showing me this error message, I have used it for a long time before today without problems. Im currently using version
3.8.2
of the plugin, I also tried with the newest version
3.9.1
with no luck.
The plugin is configured like this:

definePlugin({
  plugins: [
    // Plugin for testing GROQ queries
    visionTool(),
  ],
})
AI Update

I can see from your configuration that you're using definePlugin where you should be using defineConfig for your studio configuration file. This is likely why the Vision plugin suddenly stopped working.

The Problem

You're wrapping visionTool() in definePlugin, but definePlugin is for creating custom plugins, not for configuring your studio. Your studio configuration file (sanity.config.js or sanity.config.ts) should use defineConfig instead.

Your current code:

definePlugin({  // ❌ Wrong context
  plugins: [
    visionTool(),
  ],
})

Should be:

defineConfig({  // ✅ Correct
  plugins: [
    visionTool(),
  ],
})

The Correct Setup

Here's how your studio configuration should look:

import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'
import {visionTool} from '@sanity/vision'

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

Understanding the Difference

  • defineConfig: This is the main configuration function for your Sanity Studio. It sets up your entire studio instance including project ID, dataset, plugins, schema, and other global settings.

  • definePlugin: This is used when you're creating a custom plugin to share or reuse. You'd only use this if you were building your own plugin package, not when configuring which plugins to use in your studio.

Why It Stopped Working Today

If this was working before and suddenly broke, check if something changed in your config file. Perhaps during an update or refactor, defineConfig was accidentally changed to definePlugin. Check your version control history to see what changed.

Once you fix the configuration to use defineConfig, both version 3.8.2 and 3.9.1 of the Vision plugin should work normally. The plugin itself is stable—the issue is just that it's not being loaded properly into your studio due to the incorrect configuration wrapper.

Can you share your
sanity.config
?
export const defaultDocumentNode = (S, { schemaType }) => {
  console.log(schemaType, 'index.js')
  if (
    [
      'accommodation',
      'travelArticle',
      'attraction',
      'campaign',
      'themePage',
      'themeCollectionPage',
      'countryStartPage',
      'bundle',
      'cruise',
      'shoppingCampaign',
      'ship',
      'shipShop',
      'shipEvent',
      'shipService',
      'shipArticle',
      'restaurant',
    ].includes(schemaType)
  ) {
    return S.document().views([
      S.view.form().icon(MdEdit),
      S.view.component(SeoPreview).icon(MdRemoveRedEye).title('SEO Preview'),
      S.view
        .component(Iframe)
        .options({
          url: (doc) => {
            return resolvePreviewUrl(doc, getCurrentLanguage(doc))
          },
        })
        .icon(MdRemoveRedEye)
        .title('Web preview'),
    ])
  }
  return S.document().views([S.view.form()])
}

const sharedConfig = definePlugin({
  plugins: [
    dashboardTool({
      widgets: [
        projectInfoWidget({
          layout: {
            width: 'large',
          },
        }),
        documentListWidget({
          showCreateButton: true,
        }),
        documentListWidget({
          showCreateButton: true,
          title: 'Last Edited',
          order: '_updatedAt desc',
        }),
        documentListWidget({
          title: 'Accommodations',
          order: '_updatedAt desc',
          types: ['accommodation'],
          layout: {
            width: 'auto',
          },
        }),
        documentListWidget({
          title: 'Attractions',
          order: '_updatedAt desc',
          types: ['attraction'],
          layout: {
            width: 'auto',
          },
        }),
        documentListWidget({
          title: 'Travle Articles',
          order: '_updatedAt desc',
          types: ['travelArticle'],
          layout: {
            width: 'auto',
          },
        }),
        documentListWidget({
          title: 'Campaigns',
          order: '_updatedAt desc',
          types: ['campaign'],
          layout: {
            width: 'auto',
          },
        }),
        documentListWidget({
          title: 'Theme Pages',
          order: '_updatedAt desc',
          types: ['themePage'],
          layout: {
            width: 'auto',
          },
        }),
        documentListWidget({
          title: 'Bundles',
          order: '_updatedAt desc',
          types: ['bundle'],
          layout: {
            width: 'auto',
          },
        }),
        documentListWidget({
          title: 'Cruise',
          order: '_updatedAt desc',
          types: ['cruise'],
          layout: {
            width: 'auto',
          },
        }),

        sanityTutorialsWidget(),
      ],
    }),
    // DeskTool plugin is used to define the structure of Sanity Studio
    // <https://www.sanity.io/docs/desk-tool-api>
    deskTool({
      structure: (S) =>
        S.list()
          .title('<http://website.com|website.com>')
          .items([
            accommodation(S),
            attraction(S),
            bundle(S),
            cruise(S),
            travelArticle(S),
            travelUniverse(S),
            S.divider(S),
            globals(S),
            bookingItems(S),
            onBoard(S),
            fnb(S),
            shopping(S),
            ...S.documentTypeListItems().filter(hiddenDocTypes),
          ]),
      defaultDocumentNode,
    }),

    // Plugin for Filtering by language
    // <https://www.sanity.io/plugins/language-filter>
    languageFilter({
      supportedLanguages: supportedLanguages,
    }),
    // Plugin for testing GROQ queries
    visionTool(),
  ],
  tools: (prev, context) => {
    const isAdmin = context.currentUser.roles.find(({ name }) => name === 'administrator')
    if (isAdmin) {
      return prev
    }
    return prev.filter((tool) => tool.name !== 'vision')
  },
  schema: {
    types: schemas,
  },
  document: {
    newDocumentOptions: (prev, { creationContext }) => {
      if (creationContext.type === 'global') {
        return prev.filter((templateItem) => templateItem.templateId != 'settings')
      }
      return prev
    },
    actions: (prev, { schemaType }) => {
      if (schemaType === 'settings') {
        return prev.filter(({ action }) => !['unpublish', 'delete', 'duplicate'].includes(action))
      }
      return prev
    },
    // Adds the "Open Preview" option
    // Return a URL to use in preview
    productionUrl: (prev, context) => {
      return productionUrl(context.document)
    },
  },
  studio: {
    components: {
      logo: Logo,
    },
  },
})

// This is where we define routes, using different datasets on each of them
export default defineConfig([
  {
    name: 'default',
    title: 'Production',
    subtitle: 'Production Dataset',
    projectId: 'xxxx',
    dataset: 'production',
    plugins: [sharedConfig()],
    basePath: '/prod',
  },
  {
    name: 'staging',
    title: 'Stage',
    subtitle: 'Staging Dataset',
    projectId: 'xxxx',
    dataset: 'stage',
    plugins: [sharedConfig()],
    basePath: '/stage',
  },
])
I resolved the issue by deleting the sanity/vision objects in localstorage. Im not sure how this happened, if its a plugin error or a user error (I can at least not remember going in to localstorage and changing the sanity/vision details)

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?