Faster Studio startup with provider middleware and UI stability fixes

Published: October 13, 2026

v6.19.0

This release adds a provider middleware for lazy-loading components to improve initial load performance, fixes the navbar and UI elements from flashing or rendering incompletely on load, resolves issues with duplicate React contexts when multiple Studio instances run on the same page, and corrects various display bugs in arrays, lists, and document editing interfaces.

Updates to the Components API (beta) and preload lazy default plugin components

Adds studio.components.provider to the Components API (beta): a middleware for a component that wraps the whole studio. It renders under the studio's own providers and above StudioLayout and its loading screen's Suspense boundary, which makes it the place for a plugin to start work the studio needs early.

One such use is preloading React.lazy components. A lazy navbar, toolMenu or activeToolLayout component only starts loading once React reaches it, and the studio layout or the tool then waits for its chunk. Hold the import function, pass it to lazy(), and call it from the provider's effect: the chunk loads as soon as the studio providers commit, and the component stays out of the eager bundle.

import {lazy, useEffect} from 'react'
import {definePlugin, type ProviderProps} from 'sanity'

// MyNavbar.tsx `export default`s the component
const lazyMyNavbar = () => import('./MyNavbar')
const MyNavbar = lazy(lazyMyNavbar)

export const myPlugin = definePlugin({
  name: 'my-plugin',
  studio: {
    components: {
      provider: MyPluginProvider,
      navbar: MyNavbar,
    },
  },
})

function MyPluginProvider(props: ProviderProps) {
  useEffect(() => {
    void lazyMyNavbar()
  }, [])

  return props.renderDefault(props)
}

Keep layout and provider components themselves as plain imports: they render in the studio's first pass, before any effect could preload them, and in development the studio warns when one of them is React.lazy or a Suspense boundary. A layout that only wraps renderDefault in context providers is a provider; the built-in plugins follow both rules (the releases, scheduled publishing and scheduled drafts plugins now declare their providers that way and no longer define a layout), so the studio no longer waits for their layout chunks before its first paint.

🐛 Notable bugfixes and improvements

  • Studio no longer throws Duplicate instances of context … with incompatible versions when two copies of sanity load on one page. Each copy keeps its own React contexts, so two Studio versions can render side by side. A copy only reads providers rendered by that same copy, so plugins and custom components must still resolve sanity to the Studio's installed package rather than bundle their own. The undocumented sanity/_createContext entry point is removed.
  • Fixes array, file, image and video inputs sometimes keeping a grey (read-only) card background after a document became editable, most visibly behind the "Show all / fewer items" toggle of an array of objects when re-opening a document.
  • @sanity/vision now declares a peer dependency on sanity at ^<the version Vision was published with> instead of ^6.0.0-0. Package managers will warn when the installed sanity is older than that Vision release. Newer sanity versions in the same major still satisfy the range.
  • The Studio navbar now paints its tools and overflow menu in its first frame on load, instead of filling them in over the following frames, and user avatars show their user's color from their first frame instead of starting out gray.
  • Fixes a flash on studio load where the navbar (tool links, user avatar, right-hand buttons) and the active tool briefly reset and re-rendered once the project's feature availability had loaded. Tasks and comments no longer wait for their feature checks: the plan check only decides between the regular and the upsell experience where that UI renders (the tasks sidebar, the comments inspector, the comment buttons). If the plan check fails, the tasks sidebar and the comments panel say the feature is unavailable and the task action reports that it cannot run, instead of exposing the regular controls.
  • Whether the Schedules tool is shown in the navbar is now settled before the studio layout first paints, instead of the tool link appearing once the project's feature availability and scheduling history had loaded.
  • Document lists and list panes in Structure now end their items at the same distance from the pane edge whether or not the list scrolls; previously an overflowing list had roughly double the right-hand spacing.
  • sanity/media-library now exports VideoDefinition as the schema definition type that defineVideoField accepts — the one with fields, options, validation and initialValue, matching ImageDefinition and FileDefinition. Previously the name resolved to a reduced internal interface.
  • Adds typegen.resources (beta) to sanity.cli.ts. With it, sanity typegen generate writes one file per listed dataset and registers that dataset's schema and query types in SanitySchemasByResource and SanityQueriesByResource under its projectId.dataset key.
  • A scaffolded defineApplication now writes a name that matches the slug.
  • The sanity init --dashboard flag now adds the organization ID for studio projects.
  • Collaborator avatars now stay in stable positions when presence updates arrive.
  • Prevents the request-access screen from sending repeated requests while it loads.
  • Fixes "Used on X page" entries in the document header doing nothing after opening a document from Presentation with "Open in Structure".
Loading...
Faster Studio startup with provider middleware and UI stability fixes | Sanity Docs