Skip to content

Sanity

With Sanity your content lives in a Sanity project and your team edits it in Sanity Studio, a hosted editor generated from your site’s content model. The site reads the published content when it builds.

  1. Create a project at sanity.io/manage. A public dataset (the default production) needs no token for reading.

  2. Under API → Tokens, create a token with the Editor role, for uploading the content.

  3. Add to .env:

    Terminal window
    SANITY_PROJECT_ID=your-project-id
    SANITY_DATASET=production
    SANITY_WRITE_TOKEN=the-editor-token # keep it on your machine
  4. Generate the Studio’s schema and upload your content and photos:

    Terminal window
    pnpm cms sanity schema
    pnpm cms sanity seed

    Seeding fills an empty project. If documents already exist it stops, so edits made in Sanity are never lost by accident; add --force to replace them.

  5. Build from Sanity: set CMS=sanity (with SANITY_PROJECT_ID and SANITY_DATASET) in your host’s environment variables.

The Studio is in the studio/ folder of your project.

Terminal window
cd studio
cp .env.example .env # your project id
npm install
npm run dev # try it locally
npm run deploy # host it at <name>.sanity.studio

The first deploy asks you to log in and pick a name. It prints an app id; put it in studio/.env as SANITY_STUDIO_APP_ID so later deploys don’t ask again.

The Studio’s navigation matches the site. Single pages (home, pricing, site settings…) open directly and can’t be duplicated or deleted. Photos can be cropped, and the crop shows on the site. Articles are written in a Markdown editor.

After changing the content model, run pnpm cms sanity schema again and redeploy the Studio.

In sanity.io/manage → API → Webhooks, add a webhook:

  • URL: your host’s deploy hook (Vercel: Project → Settings → Git → Deploy Hooks; Netlify: Build hooks; Cloudflare: Settings → Builds → Deploy hooks)
  • Trigger on: create, update, delete
  • Filter: the one pnpm cms sanity schema prints

Saving a draft doesn’t start a build; publishing does.

  • Private dataset: create a token with the Viewer role and set it as SANITY_READ_TOKEN in your host’s environment variables.
  • Preview with unpublished changes: a separate deployment with SANITY_PERSPECTIVE=drafts and the Viewer token shows drafts too.