Sanity logosanity.ioAll Systems Operational© Sanity 2026
Change Site Theme
Sanity logo

Documentation

    • Overview
    • Platform introduction
    • Next.js quickstart
    • Nuxt.js quickstart
    • Astro quickstart
    • React Router quickstart
    • Studio quickstart
    • Build with AI
    • Content Lake
    • Functions
    • APIs and SDKs
    • Agent Actions
    • Visual Editing
    • Blueprints
    • Platform management
    • Dashboard
    • Studio
    • Canvas
    • Media Library
    • App SDK
    • Content Agent
    • HTTP API
    • CLI
    • Libraries
    • Specifications
    • Changelog
    • User guides
    • Developer guides
    • Courses and certifications
    • Join the community
    • Templates
Studio
Overview

  • Setup and development

    Installation
    Project Structure
    Development
    Hosting and deployment
    Embedding Sanity Studio
    Upgrading Sanity Studio
    Environment Variables
    Using TypeScript in Sanity Studio
    Understanding the latest version of Sanity

  • Configuration

    Introduction
    Workspaces
    Schema and forms
    Conditional fields
    Field Groups
    List Previews
    Connected Content
    Validation
    Initial Value Templates
    Cross Dataset References
    Sort Orders
    Visual editing and preview
    Incoming reference decoration

  • Block Content (Portable Text)

    Introduction
    Configure the Portable Text Editor
    Customize the Portable Text Editor
    Create a Portable Text behavior plugin
    Add Portable Text Editor plugins to Studio
    Common patterns
    Standalone Portable Text Editor

  • Studio customization

    Introduction
    Custom component for Sanity Studio
    Custom authentication
    Custom asset sources
    Diff components
    Form Components
    How form paths work
    Icons
    Favicons
    Localizing Sanity Studio
    New Document Options
    Studio Components
    Studio search configuration
    Focus and UI state in custom inputs
    Real-time safe patches for input components
    Sanity UI
    Studio Tools
    Create a custom Studio tool
    Tools cheat sheet
    Theming

  • Workflows

    The Dashboard tool for Sanity Studio
    Add widgets to dashboard
    Document actions
    Release Actions
    Custom document badges
    Localization
    Content Releases Configuration
    Enable and configure Comments
    Configuring Tasks
    Scheduled drafts
    Scheduled publishing (deprecated)
    Manage notifications

  • Structure builder

    Introduction
    Get started with Structure Builder API
    Override default list views
    Create a link to a single edit page in your main document type list
    Manually group items in a pane
    Dynamically group list items with a GROQ filter
    Create custom document views with Structure Builder
    Cheat sheet
    Structure tool
    Reference

  • Plugins

    Introduction
    Installing and configuring plugins
    Developing plugins
    Publishing plugins
    Internationalizing plugins
    Reference
    Official plugins repo

  • AI Assist

    Installation
    Translation
    Custom field actions
    Field action patterns

  • User guides

    Comments
    Task
    Copy and paste fields
    Compare document versions
    Content Releases
    Scheduled drafts
    View incoming references
    Common keyboard shortcuts

  • Studio schema reference

    Studio schema configuration
    Array
    Block
    Boolean
    Cross Dataset Reference
    Date
    Datetime
    Document
    File
    Geopoint
    Global Document Reference
    Image
    Number
    Object
    Reference
    Slug
    Span
    String
    Text
    URL

  • Studio reference

    Asset Source
    Configuration
    Document
    Document Badges
    Document Actions
    Form
    Form Components
    Hooks
    Structure tool
    Studio Components Reference
    Tools
    Initial Value Templates
    Studio API reference

On this page

Previous

Development

Next

Embedding Sanity Studio

Was this page helpful?

On this page

  • Hosting with Sanity
  • Undeploying the Studio
  • Hosting with Sanity in a CI/CD flow
  • Authorizing Studio deployments
  • Self-hosting the Studio
  • Specifying the base path
  • Building the Studio for hosting
  • Environment variables
  • GraphQL
StudioLast updated January 9, 2026

Hosting and deployment

How to deploy Sanity Studio, either on your own or using our hosted service.

Sanity Studio is an open-source React-based Single Page Application (SPA) that runs entirely in the browser and connects with Sanity's hosted APIs and Content Lake.

There are two primary ways of hosting Sanity Studio:

  • We can host this web application for you, giving you a nice my-company.sanity.studio URL. With a single Sanity CLI command, you can deploy and manage multiple Studios for different environments or use cases under the same project.
  • You can deploy Sanity Studio on any hosting platform that supports SPA routing.

The built-in Sanity Studio hosting is the quickest and easiest way to make the Studio accessible on the web. Self-hosting is usually preferred when you wish to use platform-specific features that are not offered by our hosting and when you want to host the Studio under your own domain.

It's also possible to embed Sanity Studio in an application as a dependency – however, depending on your setup and configuration, you might forego certain features that are tied to the build tooling that comes with the Sanity CLI.

Upgrading Sanity Studio

Hosting with Sanity

# With the CLI globally installed
sanity deploy

# Using npx
npx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
pnpm dlx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
yarn dlx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
bunx sanity deploy

Running this command from your Studio project folder builds and deploys your Studio, making it available on a *.sanity.studio URL. When you deploy, you will be asked to choose a unique hostname for your Studio.

Hostnames must begin with letters

Studio hostnames must begin with alpha characters. Numbers and symbols are not permitted.

On subsequent deploys, you can select an existing hostname in a prompt or specify it in the CLI config file (sanity.cli.js|ts) for automated deployments.

import {defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
  api: {
    projectId: 'projectid',
    dataset: 'production'
  },
  // Tip: You can use an environment variable for studioHost if you want to deploy separate Studios for production, staging, testing etc.
  studioHost: 'my-company'
})

Gotcha

The sanity deploy command works by building the source files in your Studio project into static files, which are then uploaded and served from your chosen sanity.studio domain.

Logged-in access to your Studio, and private data in your Content Lake, is always secured by authentication. However, no authentication is involved when serving the built Studio's files. Make sure not to include any sensitive data – such as authentication tokens – in your Studio's configuration files.

You will also be prompted to, optionally, add your appId to your client configuration. Doing so will enable fine-grained control of how and when your studio will auto-update in the project management settings.

export default defineCliConfig({
  //…
  deployment: {
    appId: 'marpozwf8vgzhpk6ixqjk8lg',
  },
  //…
})

Undeploying the Studio

# With the CLI globally installed
sanity undeploy

# Using npx
npx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
pnpm dlx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
yarn dlx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
bunx sanity undeploy

Run the command above to change the hostname later or remove the Studio from the web. You may choose a new hostname the next time you deploy.

The undeploy command targets the studio host defined in your sanity.cli.ts configuration. Use the environment variable strategy in the next section if you wish to enable deploying/undeploying different studio instances.

Hosting with Sanity in a CI/CD flow

You can host with Sanity automatically with continuous integration tools. This is convenient for automatically updating the hosted Studio when you push your local changes to source repositories or do manual releases. Add @sanity/cli as a development dependency and configure your CI/CD workflow to run the command sanity deploy. Remember to have the sanity.cli.ts config file in your Studio folder.

If you need to accommodate test, staging, and production deployments, then we recommend that you define the Studio host name (and other configuration) in environment variables and access them in the config file like this:

import {defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
  api: {
    projectId: process.env.SANITY_STUDIO_PROJECT_ID,
    dataset: process.env.SANITY_STUDIO_DATASET,
  },
  studioHost: process.env.SANITY_STUDIO_HOSTNAME
})

Authorizing Studio deployments

You also need to provide an authorization token using the SANITY_AUTH_TOKEN environment variable. This is because deploying with the sanity deploy command uses your local user session for authenticating with our hosting service, which won't necessarily be available in your CI/CD workflows. You can create a deploy token in the project management dashboard.

Self-hosting the Studio

Since the Studio consists of static HTML, CSS, and JavaScript files and communicates with Sanity through our HTTP API, it can be hosted anywhere. Popular hosting services like Vercel and Netlify make it possible to automatically deploy new versions of your Studio when you push it to code repositories like GitHub.

There are two things you need to make sure of when hosting the Studio yourself or with a service:

  • The server that delivers the Sanity Studio files needs to be configured for single-page application routing. This means if the requested URL path doesn't exist on the filesystem, it should serve index.html to allow the frontend router to handle the request. Most hosting services will have configuration options for this.
  • The domain for where the Studio is hosted must be added as a valid domain in the project's CORS settings. For security, the Sanity API ensures that only approved Studios can communicate with your project. This is in addition to other security measures such as user authentication, private datasets, and custom access rules.

If you host with Sanity, this is automatically handled for you. If your host does not support single-page-application routing, you can add a redirect rule to make sure non-existent paths are redirected properly. Check the documentation for your provider or server software.

Specifying the base path

Normally, the Studio expects to be hosted at the root level of its hostname; for instance https://studio.example.com/. To serve the studio on a subpath, such as https://example.com/studio, you need to edit the CLI configuration file. You'll find it as sanity.cli.js or sanity.cli.ts in the root of your Studio project.

import {defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
  project: {
    basePath: '/studio'
  },
  // ...config continued
})

The Studio can now be served from https://example.com/studio. This will also change the base path of static files.

Most cases where you embed the Studio in another application will require you to set the basePath.

Gotcha

The sanity.config.js file also has a basePath property - this defines the base path of the workspace and not the actual studio.

In other words, the two basePaths gets joined together: if the CLI base path is set to /studio and the workspace base path is /production, the resulting base path for the "production" workspace will be /studio/production.

Setting the SANITY_STUDIO_BASEPATH environment variable is an alternative method of defining the base path for the studio, and will override any value set in the configuration file.

Building the Studio for hosting

# With the CLI installed globally
sanity build

# With npx
npx sanity build

# With npx, specifying the build folder name to be "public"
npx sanity build public
# With the CLI installed globally
sanity build

# With npx
pnpm dlx sanity build

# With npx, specifying the build folder name to be "public"
pnpm dlx sanity build public
# With the CLI installed globally
sanity build

# With npx
yarn dlx sanity build

# With npx, specifying the build folder name to be "public"
yarn dlx sanity build public
# With the CLI installed globally
sanity build

# With npx
bunx sanity build

# With npx, specifying the build folder name to be "public"
bunx sanity build public

Run the command above from the studio folder to generate the files for hosting. This will output the files to the dist/ directory by default. Sometimes your environment requires another directory name, for instance public. You can specify this by entering the desired name after the build command.

Once the build is complete, the directory can be uploaded and hosted from any web hosting where you can control redirects for a Single-Page Application, like Vercel, Netlify, or Cloudflare.

Environment variables

Sometimes you want to configure the projectId , dataset or studioHost specified in sanity.cli.js and sanity.config.js at build time. This is useful for building multiple Studios from the same schema and code to facilitate different environments. See the documentation on environment variables for your options.

GraphQL

How to deploy the GraphQL APIs is covered in its own section.

  • Article
  • Changelog
# With the CLI globally installed
sanity deploy

# Using npx
npx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
pnpm dlx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
yarn dlx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
bunx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
npx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
pnpm dlx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
yarn dlx sanity deploy
# With the CLI globally installed
sanity deploy

# Using npx
bunx sanity deploy
import {defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
  api: {
    projectId: 'projectid',
    dataset: 'production'
  },
  // Tip: You can use an environment variable for studioHost if you want to deploy separate Studios for production, staging, testing etc.
  studioHost: 'my-company'
})
export default defineCliConfig({
  //…
  deployment: {
    appId: 'marpozwf8vgzhpk6ixqjk8lg',
  },
  //…
})
# With the CLI globally installed
sanity undeploy

# Using npx
npx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
pnpm dlx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
yarn dlx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
bunx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
npx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
pnpm dlx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
yarn dlx sanity undeploy
# With the CLI globally installed
sanity undeploy

# Using npx
bunx sanity undeploy
import {defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
  api: {
    projectId: process.env.SANITY_STUDIO_PROJECT_ID,
    dataset: process.env.SANITY_STUDIO_DATASET,
  },
  studioHost: process.env.SANITY_STUDIO_HOSTNAME
})
import {defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
  project: {
    basePath: '/studio'
  },
  // ...config continued
})
# With the CLI installed globally
sanity build

# With npx
npx sanity build

# With npx, specifying the build folder name to be "public"
npx sanity build public
# With the CLI installed globally
sanity build

# With npx
pnpm dlx sanity build

# With npx, specifying the build folder name to be "public"
pnpm dlx sanity build public
# With the CLI installed globally
sanity build

# With npx
yarn dlx sanity build

# With npx, specifying the build folder name to be "public"
yarn dlx sanity build public
# With the CLI installed globally
sanity build

# With npx
bunx sanity build

# With npx, specifying the build folder name to be "public"
bunx sanity build public
# With the CLI installed globally
sanity build

# With npx
npx sanity build

# With npx, specifying the build folder name to be "public"
npx sanity build public
# With the CLI installed globally
sanity build

# With npx
pnpm dlx sanity build

# With npx, specifying the build folder name to be "public"
pnpm dlx sanity build public
# With the CLI installed globally
sanity build

# With npx
yarn dlx sanity build

# With npx, specifying the build folder name to be "public"
yarn dlx sanity build public
# With the CLI installed globally
sanity build

# With npx
bunx sanity build

# With npx, specifying the build folder name to be "public"
bunx sanity build public