Sanity Best Practices
SanityOfficialPublished by Sanity
- Skill
- Tool integration
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a comprehensive collection of best practices, architectural patterns, and integration guides for the Sanity ecosystem. It covers the full development lifecycle, including schema design, GROQ query optimization, TypeGen configuration, and framework-specific integrations like Next.js, Angular, and Remix. It also includes guidance on infrastructure management via Blueprints, content automation with Sanity Functions, and building custom applications with the Sanity App SDK.
What it does
- Provides standardized patterns for Sanity schema design and content modeling.
- Offers integration guides for major frontend frameworks and the Sanity App SDK.
- Defines best practices for GROQ query performance and type safety with TypeGen.
- Outlines rules for media handling, including video asset management.
- Details configuration for Sanity Studio structure and Visual Editing.
- Explains infrastructure-as-code workflows using Sanity Blueprints.
When to use it
- When starting a new Sanity project or onboarding team members.
- When integrating Sanity with frameworks like Next.js, Astro, or Angular.
- When optimizing GROQ queries or implementing type-safe data fetching.
- When designing complex content schemas or implementing localization.
- When setting up live previews, Visual Editing, or custom Studio structures.
- When automating content workflows or managing infrastructure via Blueprints.
Advantages
- Maintained by Sanity, ensuring alignment with current platform standards.
- Reduces technical debt by enforcing consistent schema and query patterns.
- Provides clear decision matrices for complex topics like video and localization.
- Includes framework-specific guidance to accelerate frontend integration.
- Promotes maintainable project structures and type-safe development workflows.
Usage examples
- “What are the best practices for handling video in Sanity?”
- The skill advises against using standard file assets for production video due to bandwidth costs, recommending the Sanity Media Library with Mux for Enterprise plans or dedicated services like Mux, YouTube, or Vimeo for others.
- “How do I set up TypeGen for an Angular monorepo?”
- The skill provides a configuration example for studio/sanity.cli.ts to point TypeGen at the Angular source files, ensuring generated types are correctly integrated into the Angular project.
- “What is the recommended way to structure singleton documents?”
- The skill recommends using explicit document IDs for singleton documents and controlling them via the Studio Structure, while letting Sanity generate IDs for all other document types.
- “How should I fetch data in a React app using the App SDK?”
- The skill mandates wrapping data-fetching components in Suspense, using documentId as a React key, and preferring useDocuments and useDocumentProjection over raw GROQ hooks.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/sanity-io/sanity-best-practices/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip sanity-best-practices.zip -d .agents/skills
Documentation by Sanity
Sanity Best Practices
Comprehensive best practices and integration guides for Sanity development, maintained by Sanity. Use the quick reference below to load only the one or two topic files that match the task.
When to Apply
Reference these guidelines when:
Setting up a new Sanity project or onboarding
Integrating Sanity with a frontend framework (Next.js, Nuxt, Astro, Remix, SvelteKit, Hydrogen)
Writing GROQ queries or optimizing performance
Designing content schemas
Implementing Visual Editing and live preview
Working with images, Portable Text, or page builders
Configuring Sanity Studio structure
Setting up TypeGen for type safety
Implementing localization
Migrating content from other systems
Building custom apps with the Sanity App SDK
Developing or deploying a Studio or app in the Sanity Dashboard
Managing infrastructure with Blueprints
Automating content workflows with Sanity Functions or webhooks
Global Rules
Let Sanity generate
_idvalues for ordinary documents. Do not create deterministic UUIDs, slug-derived IDs, or legacy-system IDs when creating documents.Model relationships with
referencefields, then resolve related documents with GROQ lookups, source-key fields, or returned_idvalues from created documents.Use explicit document IDs mainly for singleton documents controlled by Studio Structure, including localized singletons such as
homePage-en.
Video
Do not store or serve video from Sanity
fileassets for production playback. File assets are delivered as raw downloads with no transcoding or adaptive streaming, and video traffic drives very high bandwidth usage and unexpectedly large bills.On Enterprise plans with the video add-on, use Sanity Media Library for video: uploads are transcoded and streamed adaptively via Mux. Model video fields with
defineVideoField()fromsanity/media-libraryand play them with@mux/mux-player-reactusing the asset's playback ID.On other plans, use a dedicated video service: install
sanity-plugin-mux-inputto upload and manage videos in your Mux account from the Studio, or host video on a platform such as YouTube or Vimeo and store only the embed URL in Sanity.Small clips and short previews in a
filefield are acceptable, but any user-facing video at scale must go through Media Library or a streaming service.
Quick Reference
Integration Guides
get-started- Interactive onboarding for new Sanity projectsnextjs- Next.js App Router, Live Content API, standalone Studionuxt- Nuxt integration with @nuxtjs/sanityangular- Angular integration with @sanity/client, signals, resource APIastro- Astro integration with @sanity/astroremix- React Router / Remix integrationsvelte- SvelteKit integration with @sanity/svelte-loaderhydrogen- Shopify Hydrogen with Sanityproject-structure- Standalone Studio and monorepo patternsapp-sdk- Custom applications with Sanity App SDKdashboard- Studios and apps in the Sanity Dashboard: defineApplication, local dev, deploys, Dashboard hooksblueprints- Infrastructure as Code: blueprint files, stacks, plan/deploy workflow, error recovery, CI deploysfunctions- Automating content workflows with Sanity Functions and webhooks
Topic Guides
groq- GROQ query patterns, type safety, performance optimizationschema- Schema design, field definitions, validation, deprecation patternsvisual-editing- Presentation Tool, Stega, overlays, live previewpage-builder- Page Builder arrays, block components, live editingportable-text- Rich text rendering and custom componentsimage- Image schema, URL builder, hotspots, LQIP, Next.js Imagestudio-structure- Desk structure, singletons, navigationtypegen- TypeGen configuration, workflow, type utilitiesseo- Metadata, sitemaps, Open Graph, JSON-LDlocalization- i18n patterns, document vs field-level, locale managementmigration- Content import overview (see alsomigration-html-import)migration-html-import- HTML to Portable Text with @portabletext/block-tools
How to Use
Start with the single framework or topic guide that best matches the request, then read additional references only when the task crosses concerns. Use these reference files for detailed explanations and code examples:
references/groq.md
references/schema.md
references/nextjs.mdEach reference file contains:
Comprehensive topic or integration coverage
Incorrect and correct code examples
Decision matrices and workflow guidance
Framework-specific patterns where applicable
Files
- ATTRIBUTION.mdAdded by AutoGineer873 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md5.4 KiB
- references/angular.md18.6 KiB
- references/app-sdk.md12.0 KiB
- references/astro.md4.9 KiB
- references/blueprints.md14.1 KiB
- references/dashboard.md6.5 KiB
- references/functions.md29.7 KiB
- references/get-started.md21.0 KiB
- references/groq.md14.4 KiB
- references/hydrogen.md6.8 KiB
- references/image.md3.3 KiB
- references/localization.md12.0 KiB
- references/migration-html-import.md5.2 KiB
- references/migration.md2.7 KiB
- references/nextjs.md16.3 KiB
- references/nuxt.md5.9 KiB
- references/page-builder.md8.2 KiB
- references/portable-text.md9.8 KiB
- references/project-structure.md3.5 KiB
- references/remix.md8.8 KiB
- references/schema.md12.4 KiB
- references/seo.md8.3 KiB
- references/studio-structure.md4.0 KiB
- references/svelte.md10.0 KiB
- references/typegen.md6.1 KiB
- references/visual-editing.md8.4 KiB
references/get-started.md
title: Sanity Getting Started Guide description: Use these rules when users ask to 'Get started with Sanity' or need help setting up a new Sanity project.
Sanity Getting Started Guide
Overview
Getting started with Sanity follows three phases:
Studio & Schema — Set up Sanity Studio and define your content model
Content — Import existing content or generate placeholder content via MCP
Frontend — Integrate with your application (framework-specific)
Communication Style
Keep responses succinct:
Tell the user what you did: "Created post schema with title, body, and slug"
Ask direct questions: "What kind of content are you building?"
Avoid verbose explanations of what you're about to do
Don't explain every step unless the user asks
Examples:
Good: "Schema deployed. Ready to add some content?"
Bad: "I'm going to deploy your schema to the Content Lake so that the MCP server can recognize your new document types. This will allow..."
Get Started with Sanity (Interactive Guide)
TRIGGER PHRASE: When the user says "Get started with Sanity" or similar, follow these steps.
Before starting: Let the user know they can pause and resume anytime by saying "Continue Sanity setup".
RESUME TRIGGER: If the user says "Continue Sanity setup", check what's already configured:
Does
sanity.config.tsexist (typically in astudio/folder)? → Studio is set upAre one or more custom schema types registered in the Studio config (often through a non-empty
schemaTypesexport)? → Schema existsIs there a frontend framework in
package.json? → May need integration
Do not treat files in schemaTypes/ as proof that a schema exists. The clean
Studio template includes schemaTypes/index.ts with an empty
schemaTypes array.
Resume from where they left off.
Step 0: Check Sanity MCP
Check whether Sanity MCP tools are already available before creating files.
If a local Studio exists, keep it as the source of truth. Update its schema files first, then deploy that schema before using MCP content tools.
If no local Studio exists and the user wants an MCP-managed setup, first select or create the project and dataset. Ask what content they are building, define the schema with the
schema.mdpatterns, rundeploy_schema, thendeploy_studio. Skip Phase 1 below and continue with Phase 2.Do not mix a code-managed Studio and an MCP-managed Studio without explaining which schema is authoritative.
If MCP is not configured, use the setup instructions below. The current Sanity initializer may also offer to configure MCP and install Sanity skills.
Run an authentication preflight
From the intended workspace root, run:
npx sanity@latest debugIf the User result identifies a logged-in user, prefer the account-owned
sanity init path in Step 1. Otherwise, continue directly with sanity new
below.
Start without an account with sanity.new
Without an account, sanity new creates a working full-stack app with Sanity as
the content backend in seconds. The project works immediately; claim it within
72 hours to keep it. First run this from the intended workspace root:
npx sanity@latest new --instructionsThis prints the current agent guide and creates nothing. Read and follow it before creating the project because this flow is rolling out and the CLI guide is the source of truth.
From an empty workspace, the batteries-included command is:
npx sanity@latest new "<project name>" --yesChoose the setup that fits:
New full-stack app: Use the command above. It creates a project, a Studio in
sanity/, and a Next.js app inweb/, all connected and ready to run.Existing frontend: Run the same command from the app root. The CLI detects the app and adds the
sanity/Studio without replacing the frontend.Project only: Add
--no-scaffoldwhen only the project and credentials are needed, such as for a custom setup or a framework other than Next.js. This creates no Studio or frontend files.
Tell the user the claim link and expiry immediately. Treat the claim link and robot token as secrets: never commit them or paste them into issues, PRs, or shared channels, and keep the token server-only. Do not run the authenticated initializer in Step 1 afterward.
If the robot token, claim link, or other project details are not readily available, recover the existing project instead of creating a duplicate:
npx sanity@latest projects unclaimed
npx sanity@latest projects unclaimed --project-id <projectId>The project-specific command returns full details, including the robot token. Keep its output private.
Phase 1: Studio & Schema
Step 1: Check for Existing Studio
Look for sanity.config.ts or sanity.cli.ts across the workspace — in the recommended side-by-side layout the Studio lives in its own folder (studio/, sanity/ when created by sanity new, or studio-* in some onboarding flows) next to the app folder:
If NO Studio found:
Ask: "Want to create a new Sanity Studio?"
If yes, first run
node --version. Current Sanity Studio and CLI releases require Node.js 22.12 or newer.If the authentication preflight did not identify a logged-in user, follow the
sanity.newflow above and then continue at Step 2 with the generatedsanity/Studio. The remaining bullets are for the account-ownedsanity initpath.Use
sanity initto create or select the project and dataset. If the project, organization, or dataset choice is unclear, ask the user rather than guessing.When the values are known, run
sanity initunattended from the repo root — not inside a Next.js app folder, where the CLI would switch to its embedded flow (not recommended):npx sanity@latest init --yes --project <projectId> --dataset <dataset> --template clean --typescript --output-path studioIf authentication is incomplete, ask the user to finish
sanity login, then retry. If a project, organization, or dataset choice is still missing, ask the user to provide it. Do not fall back to an interactive initializer flow.This creates a standalone Studio in
studio/, alongside your app folder (seeproject-structure.md)If the user wants the Studio to run in the Sanity Dashboard beta, add
--dashboardand follow thedashboardrule.
If Studio exists:
Read the config to get
projectIdanddatasetIf
sanity.cli.tsusesdefineApplication, it runs in the Sanity Dashboard; load thedashboardrule before runningdevordeployProceed to Step 2
Step 2: Check for Existing Schema
Inspect the types registered by sanity.config.ts, usually through
schemaTypes/index.ts, schemas/index.ts, or
src/sanity/schemaTypes/index.ts:
If NO custom types are registered:
Ask: "What kind of content are you building? (e.g., Blog, E-commerce, Portfolio)"
Create appropriate schema types based on their answer
See
schema.mdfor patterns
If custom types are registered:
Show them what you found
Ask: "Want to add more content types or modify existing ones?"
Before moving to Phase 2, keep track of the primary document type and the
fields needed to list and render it. Carry that choice through content checks,
sample content, queries, routes, and components. Never fall back to post
unless the registered primary type is actually post.
If they want a quick example: Create a basic blog schema:
// schemaTypes/post.ts
import { defineArrayMember, defineField, defineType } from 'sanity'
export const post = defineType({
name: 'post',
type: 'document',
fields: [
defineField({ name: 'title', type: 'string' }),
defineField({ name: 'slug', type: 'slug', options: { source: 'title' } }),
defineField({
name: 'body',
type: 'array',
of: [defineArrayMember({ type: 'block' })],
}),
],
})Register the type in the schema entry point:
// schemaTypes/index.ts
import { post } from './post'
export const schemaTypes = [post]Creating the file is not enough. Only types included in the array passed to
schema.types are part of the Studio schema and available to schema
deployment.
Step 3: Deploy Schema
Required before Phase 2:
Run schema commands with the detected Studio folder as the working directory. For the default side-by-side layout:
cd studio
npx sanity schemas deployThis uploads your schema to the Content Lake so MCP tools can work with it.
Phase 2: Content
Step 1: Check for Existing Content
Use MCP query_documents to check:
*[_type == "<primaryDocumentType>"][0...5]Replace <primaryDocumentType> with the registered type selected in Phase 1,
such as post, product, or project.
If content exists:
Show them a summary
Ask: "Want to add more content or move to frontend integration?"
If NO content:
Ask: "Do you want to:
Import existing content (from another CMS, markdown, etc.)
Generate sample content with AI
Skip this and add content manually in the Studio"
Step 2a: Import Existing Content
If migrating from another CMS or files:
See
migration.mdand thesanity-migrationskill for guidanceUse MCP content tools such as
create_documentsandpatch_documentsafter converting content to structured Sanity documents
Step 2b: Generate Sample Content (MCP)
Ask the agent to draft structured sample content that matches the selected primary document type, then create it with the Sanity MCP Server.
For the quick blog example above:
Tool: create_documents
Documents: [{
type: "post",
content: {
title: "Getting started with Sanity",
slug: { _type: "slug", current: "getting-started-with-sanity" },
body: []
}
}]The content tool creates a draft. Show the draft to the user and ask whether to
publish it so the public frontend can read it. If yes, call
publish_documents with the returned document ID before starting frontend
integration.
If MCP content tools cannot see new types or fields: Remind them to run npx sanity schemas deploy first.
MCP Setup (If Not Configured)
Quick start via Sanity CLI:
npx sanity@latest mcp configureThis command detects Codex, Cursor, Claude Code, VS Code, and other supported editors. Prefer it over editing client configuration by hand.
Codex (manual fallback): Register the server globally and authenticate in one command:
codex mcp add sanity --url https://mcp.sanity.ioCursor: One-click install →
Or add to .cursor/mcp.json:
{
"mcpServers": {
"Sanity": {
"type": "http",
"url": "https://mcp.sanity.io"
}
}
}Claude Code:
claude mcp add Sanity -t http https://mcp.sanity.io --scope userVS Code: Command Palette → MCP: Open User Configuration → add:
{
"servers": {
"Sanity": {
"type": "http",
"url": "https://mcp.sanity.io"
}
}
}Phase 3: Frontend Integration
Client Bundle Warning (Vite-based frameworks)
React Router, SvelteKit, Astro, and Nuxt all run on Vite. Any module imported by a client component will be bundled to the browser. process.env doesn't exist there.
For publishable values (projectId, dataset, apiVersion, public studio URL), use the framework's client-safe env mechanism:
React Router / Remix:
import.meta.env.VITE_*SvelteKit:
$env/static/publicAstro:
import.meta.env.PUBLIC_*Nuxt:
useRuntimeConfig().public
For secrets (read tokens, webhook secrets), read process.env.* (or the server equivalent) only from server-only modules — .server.ts, route handlers, API endpoints. Don't centralize them in a shared env.ts that anything else imports.
This trap is invisible at SSR — the page renders fine on first load. It surfaces on client-side route transitions, when a lazy-loaded route chunk pulls a shared client/image module into the browser.
Step 1: Find the App and Detect Framework
The working directory is often a parent folder with the Studio and the app side by side. Identify the app folder first: a sibling of the Studio folder with its own package.json (commonly web/). If several candidates exist, ask the user which app to integrate — never assume.
Check the app's package.json dependencies:
| Dependency | Framework | Rule File |
|---|---|---|
next | Next.js | nextjs.md |
@remix-run/react or react-router | React Router / Remix | remix.md |
svelte or @sveltejs/kit | SvelteKit | svelte.md |
nuxt | Nuxt | nuxt.md |
astro | Astro | astro.md |
If NO framework found:
Ask: "Which framework are you using, or would you like to create a new app?"
Guide them to create one or specify their choice
Step 2: Next.js Integration (Inline)
If Next.js is detected, follow these essential steps:
The inline implementation below continues the quick Blog example. If the
primary document type is not post, adapt the type filter, projection, sample
document, route, component names, and renderer to the fields selected in Phase
Do not create or query
postas a fallback for E-commerce or Portfolio setups.
Scaffold a new app (if you don't have one yet):
Run from the repo root so the app sits alongside your studio/ folder:
npx create-next-app@latest web --tailwind --ts --app --src-dir --eslint --import-alias "@/*" --turbopack
cd webInstall dependencies:
npm install next-sanity @sanity/image-urlnext-sanity is the official Sanity toolkit for Next.js. It bundles @sanity/client, groq (with defineQuery), and @portabletext/react, plus dedicated subpath exports for Next.js-specific features:
next-sanity—createClient,defineQuery,PortableText,SanityDocument,stegaCleannext-sanity/live—defineLivefor live content with Next.js cache integrationnext-sanity/draft-mode— Draft Mode endpoint helpersnext-sanity/visual-editing—<VisualEditing />component for click-to-edit overlaysnext-sanity/image— Sanity-aware<Image />wrappingnext/imagenext-sanity/studio— embed the Sanity Studio at a route (legacy setups only — keep the Studio standalone, seenextjs.md)next-sanity/webhook— webhook signature verification
Don't also install @sanity/client, @portabletext/react, or groq directly — import them from next-sanity. @sanity/image-url is not bundled (yet), so add it separately.
Create the client (src/sanity/client.ts):
import { createClient } from "next-sanity";
export const client = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET!,
apiVersion: "YYYY-MM-DD", // Replace with today's UTC date and keep it hard-coded
useCdn: true, // Fast, cached published-content reads
});Fetch content in a Server Component:
// src/app/page.tsx
import { client } from "@/sanity/client";
import { defineQuery, type SanityDocument } from "next-sanity";
import Link from "next/link";
const POSTS_QUERY = defineQuery(
`*[_type == "post" && defined(slug.current)] | order(_createdAt desc){ _id, title, slug }`
);
const options = { next: { revalidate: 30 } };
export default async function PostsPage() {
const posts = await client.fetch<SanityDocument[]>(POSTS_QUERY, {}, options);
return (
<ul>
{posts.map((post) => (
<li key={post._id}>
<Link href={`/${(post.slug as { current?: string })?.current}`}>{post.title as string}</Link>
</li>
))}
</ul>
);
}{ next: { revalidate: 30 } } opts the fetch into Next.js' ISR cache with a
30-second revalidation window. This is a minimal published-content path for a
first smoke test. Tune to taste; omit options to use defaults.
Render an individual post (src/app/[slug]/page.tsx):
import { PortableText, defineQuery, type SanityDocument } from "next-sanity";
import { notFound } from "next/navigation";
import { client } from "@/sanity/client";
const POST_QUERY = defineQuery(
`*[_type == "post" && slug.current == $slug][0]{ _id, title, body }`
);
const options = { next: { revalidate: 30 } };
export default async function PostPage({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const post = await client.fetch<SanityDocument | null>(POST_QUERY, { slug }, options);
if (!post) return notFound();
return (
<article>
<h1>{post.title as string}</h1>
{Array.isArray(post.body) && <PortableText value={post.body} />}
</article>
);
}Add environment variables (.env.local):
NEXT_PUBLIC_SANITY_PROJECT_ID=your-project-id
NEXT_PUBLIC_SANITY_DATASET=productionConfigure TypeGen before calling the Next.js setup complete:
Merge the TypeGen settings into the existing studio/sanity.cli.ts. For the
side-by-side studio/ and web/ layout:
typegen: {
enabled: true,
path: '../web/src/**/*.{ts,tsx,js,jsx}',
schema: 'schema.json',
generates: '../web/sanity.types.ts',
overloadClientMethods: true,
},Add a repeatable script to studio/package.json:
"typegen": "sanity schemas extract --force && sanity typegen generate"Then run it from the Studio folder:
cd studio
npm run typegenConfirm TypeGen found the frontend queries, then remove the SanityDocument
import, broad generic arguments, and casts. Run TypeGen after schema or query
changes. For other layouts, use typegen.md to adjust the paths.
For the recommended production path—live content with defineLive, Visual
Editing, and the standalone Studio architecture—follow nextjs.md.
Step 3: Other Frameworks
For non-Next.js frameworks, read the corresponding rule file and follow its integration guide:
React Router / Remix:
remix.mdSvelteKit:
svelte.mdNuxt:
nuxt.mdAstro:
astro.md
Each rule file contains framework-specific patterns for data fetching, Portable Text rendering, and Visual Editing.
Step 4: Smoke Test
Before declaring integration done, exercise both render paths:
npm run dev(in the app folder)Load the home page (lists the selected content type).
Click through to a detail page via the in-app Next.js
<Link>— do not paste the URL.Open the browser console. It should be clean. No
ReferenceError: process is not defined, no hard reload to/.For good measure, reload the detail page directly (URL bar) — that exercises SSR.
Server-side rendering passing isn't enough. Client-side route transitions pull lazy chunks that exercise different code paths, and that's where env/bundling traps surface.
What's Next
Once setup is complete, let the user know:
"You're all set! Here are some things I can help with:
Visual Editing — Click-to-edit in the Presentation tool (
visual-editing.md)TypeGen — Type-safe queries with generated types (
typegen.md)Studio Structure — Customize the Studio sidebar (
studio-structure.md)SEO — Metadata, sitemaps, and Open Graph (
seo.md)i18n — Multi-language content (
localization.md)
Just ask about any of these!"
Environment Variables
Framework-Specific Prefixes
| Framework | Client-Side Prefix | Example |
|---|---|---|
| Next.js | NEXT_PUBLIC_ | NEXT_PUBLIC_SANITY_PROJECT_ID |
| React Router / Remix | VITE_ | VITE_SANITY_PROJECT_ID |
| SvelteKit | PUBLIC_ | PUBLIC_SANITY_PROJECT_ID |
| Nuxt | NUXT_PUBLIC_ | NUXT_PUBLIC_SANITY_PROJECT_ID |
| Astro | PUBLIC_ | PUBLIC_SANITY_PROJECT_ID |
Secrets (read tokens, webhook secrets) stay unprefixed and are read via process.env (or the framework's server-only equivalent) from server-only modules — *.server.ts, route handlers, API routes. Never re-export a secret from a module that a route component can import.
Common Commands
npx sanity@latest new --instructions # Print the current no-write sanity.new guide
npx sanity@latest debug # Check the current CLI user without logging in
npx sanity@latest init # Initialize an account-owned project or Studio
npx sanity@latest mcp configure # Configure MCP for your editor
npx sanity dev # Start Studio locally
npx sanity schemas deploy # Deploy schema for MCP/editor access
npx sanity deploy # Deploy Studio to Sanity hosting
npx sanity manage # Open project settings
npm run typegen # Generate types (run in Studio after adding the script above)Important Notes
Be succinct — Guide step-by-step without over-explaining
Check context first — Read existing files before suggesting changes
Don't give up — If something fails, give the user a way to complete manually
Deploy schema early — MCP content tools need deployed schemas to see new types and fields
One phase at a time — Complete each phase before moving to the next
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Sanity
- Publisher
- Sanity (Official)
- Source
- sanity-io/agent-toolkit · skills/sanity-best-practices · commit 3ed3a14
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Sanity or Sanity.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download sanity-best-practices.zip