App SDK v2 to v3
Upgrading to @sanity/sdk-react 3.0.0 changes the project and organization hooks to background revalidation, removes deprecated APIs, moves utilities to dedicated entry points, and simplifies resource configuration.
@sanity/sdk-react 3.0.0 is a breaking release. The project and organization hooks now revalidate their data in the background, several long-deprecated APIs are gone, and a few utilities moved to dedicated entry points. It also adds hooks for permission checks, application and installation management, and mutations.
If none of the sections below apply to your app, this is a one-line upgrade. Otherwise, work through them in order.
Prerequisites
- An app running
@sanity/sdk-reactv2. - React 19.2 or later. v3 raises the React peer dependency to
^19.2.0, so upgradereactandreact-domfirst if you are below that.
Install version 3
Install the v3 release with your package manager of choice:
npm install @sanity/sdk-react@^3pnpm add @sanity/sdk-react@^3If your app also depends on @sanity/sdk directly, upgrade it to v3 at the same time. The two packages are released together.
Update project and organization hook call sites
useProject, useProjects, useDatasets, useOrganization, and useOrganizations now return a result object instead of the raw value: {data, isFetching, error, refetch}. Each hook still suspends until its first fetch succeeds, so data is always available once your component renders.
Replace direct reads of the hook's return value:
const project = useProject({projectId})With a read of its data property:
const {data: project} = useProject({projectId})Fetched data stays fresh for 30 seconds. After that, the hook keeps serving the cached value while it refetches in the background, so a mounted component can pick up new data without remounting. Check isFetching to tell a background refresh apart from settled data, and call refetch to force a fresh read.
A background refetch that fails no longer reaches your error boundary. Only the initial fetch throws; after that, a failed revalidation surfaces through the hook's error property while the last successful value keeps rendering.
See the React hooks reference for the full hook list.
Update agent, comlink, and dashboard imports
Agent functions and low-level comlink utilities now live in their own entry points instead of the main @sanity/sdk export. Replace root imports:
import {agentGenerate, type AgentGenerateOptions, type FrameMessage} from '@sanity/sdk'With the dedicated entry points:
import {agentGenerate, type AgentGenerateOptions} from '@sanity/sdk/agent'
import {type FrameMessage} from '@sanity/sdk/comlink'Dashboard hooks moved to @sanity/sdk-react/dashboard, and two were renamed along the way: useDashboardOrganizationId is now useOrganizationId, and useDashboardNavigate is now useNavigate.
Remove uses of deprecated APIs
A set of APIs that were deprecated in earlier versions are now removed:
- The
sourceoption on handles,sourceNameon hooks, and thesourcesconfig option are gone. Useresource,resourceName, and theresourcesprop on<SanityApp>instead. DocumentSource,DatasetSource,MediaLibrarySource, andCanvasSourceare replaced byDocumentResource,DatasetResource,MediaLibraryResource, andCanvasResource.getPreviewStateandresolvePrevieware replaced bygetProjectionStateandresolveProjection, each with an explicitprojection. TheuseDocumentPreviewhook is unaffected.- The
studioModeconfig option,ValidProjectiontype,sanityConfigsprop, andProjectWithoutMemberstype are removed in favor ofstudio,string,config, andProject, respectively. - A set of helpers that were never intended for use outside the SDK's React layer are no longer exported:
isStudioConfig,getClientErrorApiBody,getClientErrorApiDescription,getClientErrorApiType,isProjectUserNotFoundClientError,ApiErrorBody,PREVIEW_PROJECTION,transformProjectionToPreview,getQueryKey,parseQueryKey,getUsersKey,parseUsersKey, andcreateGroqSearchFilter. If your app depends on one of these, open an issue describing your use case.
Pass a resource instead of creating child instances
useSanityInstance no longer accepts a config argument, and SanityInstance.getParent(), createChild(), and match() are removed. To scope an operation to a different project or dataset, pass an explicit resource to the operation instead.
Replace the v2 form:
const child = instance.createChild({projectId: 'other', dataset: 'production'})
applyDocumentActions(child, {actions})With the v3 form:
applyDocumentActions(instance, {actions, resource: {projectId: 'other', dataset: 'production'}})The plural resources config option is also removed; named resources are now purely a React-layer concept, set through the resources prop on <SanityApp> and <SDKProvider>. In its place, the singular resource option on SanityConfig now works as the instance's default: any call that doesn't pass its own resource uses it automatically, including calls against a media library or Canvas resource. See document handles for more on configuring resources.