Migrate an SDK app to Dashboard 2.0
Move an existing SDK app to utilise Dashboard 2.0: upgrade to App SDK v3, switch to defineApplication, and deploy it as a new application.
1Where your app renders now
Your App SDK app rendered into a single full-page surface. In Dashboard 2.0 that surface is called the window view, and it is still the default. If you set entry in defineApplication, the CLI creates the window view for you and your app renders exactly where it used to.
What changes is that defineApplication is now a container rather than a single app surface. One application has one job, but it can render parts of that job on several surfaces: a window view, one or more panel views in the column beside the dock, a tile view on the home page, and web workers running in the background. You opt into the extra surfaces only when you need them.
2Prerequisites
- An SDK app with a
sanity.cli.tsfile. - React 19.2 or later.
- Your organization ID. Your existing
sanity.cli.tsalready has it asapp.organizationId.
3Upgrade to SDK v3
Dashboard 2.0 signs your app in and passes it the current organization over its message bus. SDK 3.9.0 and later support this. If you're upgrading from v2, follow App SDK v2 to v3 for the breaking changes.
npm install @sanity/sdk@latest @sanity/sdk-react@latest react@latest react-dom@latest npm install --save-dev sanity@latest
pnpm add @sanity/sdk@latest @sanity/sdk-react@latest react@latest react-dom@latest pnpm add --save-dev sanity@latest
4Switch the configuration to defineApplication
Wrap app in defineApplication, add slug, name, and title, and remove deployment.appId:
organizationId: Keep your existing value.entry: Set it explicitly,defineApplicationdoesn't default to./src/App.tsx.slug: The app's slug in Dashboard and the hostname it deploys to. Slugs are currently unique across all organizations, so choose one specific to your app.name: The app's stable identity. You can't change it after the first deploy. Defaults toslug.title: The label on the Dashboard dock button.
You don't need to change src/App.tsx. Keep its default export and the SanityApp config, which still sets the project and dataset your app reads from. You can see a before & after example below:
import {defineCliConfig} from 'sanity/cli'
export default defineCliConfig({
app: {
organizationId: 'your-organization-id',
entry: './src/App.tsx',
},
deployment: {
appId: 'your-app-id',
},
})import {defineApplication, defineCliConfig} from 'sanity/cli'
export default defineCliConfig({
app: defineApplication({
organizationId: 'your-organization-id',
slug: 'content-app',
name: 'content-app',
title: 'Content app',
entry: './src/App.tsx',
}),
})5Run the app in the Dashboard
The CLI starts a local Dashboard on the configured port (3333 by default). Open the Dashboard URL the CLI prints. You no longer need --load-in-dashboard; the CLI ignores it for these apps. If you run multiple apps locally they’ll all connect to the same local Dashboard
npx sanity devpnpm dlx sanity dev
yarn dlx sanity dev
bunx sanity dev6Deploy the new application
The first deploy creates a new application and prints its URL. The CLI then prints a deployment.appId. Add it to sanity.cli.ts so later deploys update this application instead of creating another.
If you want to keep this new app hidden from users whilst you migrate and test then set visibility: 'unlisted' in the defineApplication function. See Application Visibility for more information.
Deploying creates a new application
You can't convert an application you've already deployed. Deploying with defineApplication creates a new application at a new URL, and the existing application stays in your organization until you undeploy it.
Apps you don't migrate keep working in Dashboard 2.0 however they will not receive new features.
npx sanity deploypnpm dlx sanity deploy
yarn dlx sanity deploy
bunx sanity deploy7Undeploy the existing app (optional)
Until you remove it, the existing app appears in the Dashboard next to the new one. To remove it with the CLI, run sanity undeploy from a copy of the project that still has the old configuration, with deployment.appId. Once sanity.cli.ts uses defineApplication, sanity undeploy targets the new application instead:
npx sanity undeploypnpm dlx sanity undeploy
yarn dlx sanity undeploy
bunx sanity undeploy