Skip to content




How to deploy Sanity with GitHub Actions

How to deploy Sanity with GitHub Actions

Learn how to deploy Sanity Studio using GitHub Actions: a working workflow file, token setup, and fixes for the common deployment failures.


Click me for the TL;DR (too long; didn't read)

Tired of manual Sanity Studio updates? Automate with GitHub Actions for error-free, fast deployments. Skip the fluff, embrace efficiency. If you read this whole thing, congrats on wasting time. Get with the program and automate already!

If you’ve ever pushed a small update to Sanity Studio only to realize you still need to manually deploy it, you know how frustrating it gets.

That’s where GitHub Actions comes in. Automate the Studio deployment and every push to main goes live on its own, with nobody waiting on a manual deploy.

With this setup, you stay focused on building features while GitHub Actions runs the same deployment steps on every push.

GitHub Actions for faster, smoother deployment

GitHub Actions is GitHub’s built-in CI/CD (Continuous Integration/Continuous Deployment) tool. You define workflows in YAML files and trigger them on specific events, such as code commits, pull requests, or scheduled intervals.

Sanity CMS, meanwhile, is a headless content management system where developers model structured content for their applications. It has a real-time collaborative editing environment and a content API you can query from anywhere.

And with the latest updates from Sanity and GitHub, deploying your Studio is smoother and safer than ever.

Why use GitHub Actions for Sanity CMS deployment?

Manual deployments eat up time and increase the chance of errors. Wire GitHub Actions and Sanity together and the Studio deploys itself on every merge: nobody forgets a deploy, nobody ships the wrong branch, and the person who wrote the change doesn’t need to remember a CLI command to get it live.

Configuring workflow triggers

In the workflow file, it's paramount to define the triggers that will initiate the deployment process. GitHub Actions provides several event types that can trigger workflows, such as push events, pull requests, and scheduled intervals.

Here’s an example of how you can configure a workflow to trigger on a push to the ‘main’ branch:

yaml
name: Deploy sanity studio

on:
  push:
    branches: [main]

In this e.g., the workflow runs whenever a push occurs on the ‘main’ branch. You can customize the triggers as per your needs.

Getting started with GitHub Actions

Now that you know how triggers work, let’s create the actual workflow file in your repository. This file defines the steps GitHub Actions will run whenever your chosen event (like a push to ‘main’) occurs.

Setting up a GitHub repository

Before utilizing GitHub Actions for CMS, you need a repository on GitHub (if you already have one, skip this step). Otherwise:

  1. Log in to your GitHub account and navigate to the main page.
  2. Click "New" near the top-left corner.
  3. Provide a meaningful repository name and description (optional).
  4. Choose public or private, depending on your needs.
  5. Select "Initialize" with a "README" (it's optional but recommended).
  6. Click "Create repository".

Creating a workflow file

Once you’ve created your repository, create a workflow file to define the deployment process. The workflow tells GitHub Actions what to do when specific events (like a push to ‘main’) occur. Follow these steps:

  1. In your repository, go to the "Actions" tab.
  2. Click "Set up a workflow yourself", or pick a template.
  3. Name your workflow file (e.g., deploy-sanity.yml).
  4. Make sure it ends with .yml (YAML syntax).
  5. Open the file in your editor and add the workflow instructions (we’ll show you an updated example in the next section).

Know more from GitHub Actions workflow tutorial (opens in new tab).

No spam, only good stuff

Subscribe, for more hot takes

Only god knows why anybody would purposefully subscribe themselves to a newsletter that moans about development. These poor souls did though
Profile 1
Profile 2
Profile 3
Profile 4
Profile 5

Configuring Sanity for deployment

Before deploying with GitHub Actions for CMS, make sure you have a few essentials ready:

  1. Sanity project: Either create a new project or use an existing one. For a quick start, check out our Working with Turbo Start Sanity guide to bootstrap your project in minutes. Make sure your schema is defined. Read Sanity CMS deployment guide (opens in new tab)
  2. API token: Generate a token with ‘Deploy Studio’ permissions and add it to your GitHub repository secrets as SANITY_AUTH_TOKEN.
  3. Add CI Specific secrets like
  4. SANITY_STUDIO_PROJECT_ID
  5. SANITY_STUDIO_DATASET
  6. SANITY_STUDIO_TITLE
  7. SANITY_STUDIO_PRESENTATION_URL
  8. Deployment provider: Decide where your Studio will live Vercel, Netlify, AWS Amplify, or another provider. For insights on Sanity and Next.js integration best practices, check out our comprehensive takeaways from real-world projects.

Once that’s in place, here’s an updated workflow example using the latest Sanity GitHub Action:

yaml
name: Deploy Sanity Studio
on:
  push:
    paths:
      - "apps/studio/**"
      - ".github/workflows/deploy-sanity.yml"
  workflow_dispatch:

permissions:
  contents: read
  id-token: write

jobs:
  deploy:
    name: Build and Deploy Sanity Studio
    runs-on: ubuntu-latest
    timeout-minutes: 15
    env:
      SANITY_AUTH_TOKEN: ${{ secrets.SANITY_AUTH_TOKEN }}
      NODE_OPTIONS: "--max_old_space_size=4096"
      PNPM_VERSION: 10.12.2
      SANITY_STUDIO_PROJECT_ID: ${{ secrets.SANITY_STUDIO_PROJECT_ID }}
      SANITY_STUDIO_DATASET: ${{ secrets.SANITY_STUDIO_DATASET }}
      SANITY_STUDIO_TITLE: ${{ secrets.SANITY_STUDIO_TITLE }}
      SANITY_STUDIO_PRESENTATION_URL: ${{ secrets.SANITY_STUDIO_PRESENTATION_URL }}
      HOST_NAME: ${{ github.head_ref || github.ref_name }}  

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: Install pnpm
        uses: pnpm/action-setup@v2
        with:
          version: ${{ env.PNPM_VERSION }}
          run_install: false

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile --ignore-scripts --prefer-offline
        
      - name: Deploy Sanity Studio
        if: steps.check-dependabot.outputs.is_dependabot != 'true'
        working-directory: ./apps/studio
        run: |
          echo "Deploying Sanity Studio..."
          pnpm run deploy
        env:
          CI: true

This workflow:

  • Uses the latest Sanity GitHub Action (v0.8-alpha)
  • Supports custom studio paths for monorepos

Sanity CMS development. Automated deployments, CI/CD pipelines, and Sanity infrastructure setup.

Sanity Preferred agency partner

What’s new in Sanity Studio?

Sanity Studio is now at v4.9.0 (2025). With v4, the CLI is more powerful, sanity.cli.ts config is flexible, at the same time, some old commands or flags no longer work.

To avoid frustrating "command not found" errors, always check your Studio version and update your workflows accordingly.

Security and token management

Security is critical in CI/CD. Here’s the safest way to handle it:

  1. Create a "Deploy Token" inside Sanity
  2. Store it in GitHub Secrets (Settings → Secrets → Actions) as SANITY_DEPLOY_TOKEN
  3. Never hardcode tokens into your workflow file
  4. For multiple environments (staging/prod), create separate tokens & datasets, and load them dynamically via secrets

Sanity now supports flexible sanity.cli.ts config, so you can pass environment-specific project IDs, datasets, and hosts cleanly.

Troubleshooting your deployment

Even with a smooth setup, issues can happen. Here are some common ones and quick tips to fix them:

  1. Authentication errors: Check that your API tokens are correct and stored in GitHub secrets.
  2. Build failures: Review logs for missing dependencies or syntax errors, and fix them in your project.
  3. Deployment timeouts: Large projects may exceed workflow limits, optimize your build or adjust timeout settings.

GitHub Actions provides detailed logs to help you pinpoint problems and debug efficiently.

Best practices we’ve learned

Over time, here are a few things that has made our deployment easier:

  1. Ignore clutter: Add .sanity to .gitignore
  2. Monorepos made easy: Use studioPath or SANITY_STUDIO_CONFIG_PATH
  3. Double check: Skim GitHub Action logs after each deploy, they catch 90% of issues early

Conclusion

The days of manually pushing Sanity Studio builds are gone. Set the workflow up once and every merge to main ships the Studio for you, the same way, every time. The half hour it takes to configure pays for itself in the first week.

Recent Sanity CLI updates made this easier too: flexible sanity.cli.ts config and safer token handling mean the workflow file above is shorter than it would have been a year ago.

If your Studio still ships by hand, this is a good afternoon project. It's also one of the first things we set up when we take on an existing Sanity studio.

Frequently asked questions

Why should I deploy Sanity Studio with GitHub Actions?
Manual Studio deploys are easy to forget and easy to get wrong. With a GitHub Actions workflow, every merge to main runs the same deployment steps automatically, so nobody has to remember a CLI command or worry about shipping the wrong branch.
What triggers the Sanity deployment workflow?
You define triggers in the workflow YAML file. Our example runs on a push to the main branch, filtered to changes under the Studio folder and the workflow file itself, and also allows manual runs through workflow_dispatch.
Which secrets does a Sanity GitHub Actions workflow need?
A Sanity token with Deploy Studio permissions stored as a GitHub secret, plus CI-specific values such as SANITY_STUDIO_PROJECT_ID, SANITY_STUDIO_DATASET, SANITY_STUDIO_TITLE and SANITY_STUDIO_PRESENTATION_URL. Never hardcode tokens into the workflow file.
How do I handle staging and production Studio deployments?
Create separate deploy tokens and datasets for each environment and load them through GitHub secrets. Sanity's sanity.cli.ts config lets you pass environment-specific project IDs, datasets and hosts without duplicating the workflow.
Does the workflow work in a monorepo?
Yes. The example sets working-directory to ./apps/studio before running the deploy script. You can also point the action at a custom Studio location with studioPath or SANITY_STUDIO_CONFIG_PATH.
Why is my Sanity Studio deployment failing in GitHub Actions?
The common causes are authentication errors from a missing or wrong token in GitHub secrets, build failures from missing dependencies or syntax errors, and timeouts on large projects. The workflow logs usually show the cause; skimming them after each deploy catches most problems early.
How long does it take to set up automated Sanity deployments?
About half an hour to configure the workflow once. After that every merge to main deploys the Studio the same way, which pays back the setup time within the first week.

About the author

Hrithik Prasad

Tech Lead with expertise in React, Next.js, and Sanity CMS. Loves building performant web applications and sharing knowledge through technical content.



Related posts





Get in touch

Tell us what you're building. We reply within one working day. Jono or someone on the team picks up every message personally.

By sending this you agree to our privacy policy. We only use your details to reply.