Skip to content




Using cursor to improve your Sanity DX

Using cursor to improve your Sanity DX

We're a little lazy, and frankly who wouldn't be with all this AI promising to replace us within 10 years? Why not use it to automate Sanity schema generation.


So you've discovered Cursor and want to dip your toes into improving your Sanity DX with artificial intelligence? Well, let's take you on a trip and share you some cheat codes along the way!

A bit of background

If you're brand new to Cursor and you want to start work with Sanity I advise a couple of things

  • Indexing all of Sanity's documentation
    • This makes working with Sanity more contextually accurate (at least from our experience). It also allows you to @sanity within a prompt if you want to solve something specific to Sanity.
  • Adding our code to the "Rules for AI"
    • This gives our opinionation to any future prompts you use. Just be aware we are very Sanity, Tailwind and Next.js focused, adjust accordingly for your projects.
  • Enabling Co-pilot ++ beta
    • This was a little rough when first released, but now it has given us some great code improvement freebies, so we'd advise turning it on.

Video of adding Sanity indexing to Cursor

Video of adding our schema and enabling co-pilot ++ beta

TL;DR let me steal your code

Alright, well at least you asked nicely. Here's the code we use for our cursor config:

markdown
Always use tailwind to style if the codebase is using it. Always use functional react. 
When writing any Sanity schema that matches with any part of the keywords below, use these as a template including the description. Make sure description is always above type. Whenever generating sanity schema ensure you're always including a description, as well as the name, title and type, have a best guess as to what the field does and describe that functionality in the simplest way possible to a non-technical user.
{
	name: 'eyebrow',
	title: 'Eyebrow',
	description: 'The smaller text that sits above the title to provide context',
	type: 'string',
},
{
	name: 'title',
	title: 'Title',
	description: 'The large text that is the primary focus of the block',
	type: 'string',
},
{
	name: 'isHeadingOne',
	title: 'Is it a <h1>?',
	type: 'boolean',
	description:
	'By default the title is a <h2> tag. If you use this as the top block on the page, you can toggle this on to make it a <h1> instead',
	initialValue: false,
},
{
  name: 'portableText',
  title: 'Portable Text',
  description: 'Large body of text that has links, ordered/unordered lists and headings.',
	type: 'portableText',
},
{
	name: 'buttons',
	title: 'Buttons',
	description: 'Add buttons here, the website will handle the styling',
	type: 'array',
	of: [{type: 'button'}],
},
{
    name: 'image',
    title: 'Image',
    type: 'image',
    fields: [
      {
        name: 'alt',
        type: 'string',
        description:
          "Remember to use alt text for people to be able to read what is happening in the image if they are using a screen reader, it's also important for SEO",
        title: 'Alt Text',
      },
    ],
  },

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

Why did you structure your code that way?

There's probably a lot that could be improved but it gives you a solid foundation to start with.

Let me break it down, and tell you why we use each section.

markdown
Always use tailwind to style if the codebase is using it. Always use functional react.

This is a nice easy one, 9 times out of 10 we're using tailwind when we are styling a project. There's literally no reason not to use Tailwind outside of "It looks bad". It's cleaner, it's easier to revisit and if you're sick of it not wrapping and can't read lines longer than the London marathon pick up our tailwind tips here

markdown
When writing any Sanity schema that matches with any part of the keywords below, use these as a template including the description. Make sure description is always above type.

Now we get into the actual Sanity content. The shorthand is. Our internal best practice is always including a description on core fields. What do we mean by "core fields". Titles, Descriptions, Images etc. Nothing more complicated than that.

We also recommend including them in this order:

  1. Title
  2. Name
  3. Description
  4. Type
  5. Validation
  6. Options

In this case, anything that's highlighted in bold above we would recommend using on **every **schema. It just helps to contextualise each field.

We'll return to this at a later date though, because we'll end up waffling and I want to write more about our internal Sanity Best Practices, because we sure as hell have a lot of opinions on how to structure schema.

text
Whenever generating sanity schema ensure you're always including a description, as well as the name, title and type, have a best guess as to what the field does and describe that functionality in the simplest way possible to a non-technical user.

The reason we're doing this should be pretty self explainatary, but let me condescend you if I haven't already. You do this because users, clients & marketers find it difficult to be on the same wave length as a developer. Ninety percent of the time we're-six-feet deep in documentation so we often make assumptions how a user will use the CMS. In the real world, this never actually happens. So for the sake of the future UX of your team, make sure you document the hell out of your schema by using **descriptions. **Even if it's not perfect, it's a large step forward from a blank field without context.

This leads us onto the actual schema we use for the rest of the prompt.

text
{
	name: 'eyebrow',
	title: 'Eyebrow',
	description: 'The smaller text that sits above the title to provide context',
	type: 'string',
},
{
	name: 'title',
	title: 'Title',
	description: 'The large text that is the primary focus of the block',
	type: 'string',
},
{
	name: 'isHeadingOne',
	title: 'Is it a <h1>?',
	type: 'boolean',
	description:
	'By default the title is a <h2> tag. If you use this as the top block on the page, you can toggle this on to make it a <h1> instead',
	initialValue: false,
},
{
  name: 'portableText',
  title: 'Portable Text',
  description: 'Large body of text that has links, ordered/unordered lists and headings.',
	type: 'portableText',
},
{
	name: 'buttons',
	title: 'Buttons',
	description: 'Add buttons here, the website will handle the styling',
	type: 'array',
	of: [{type: 'button'}],
},
{
    name: 'image',
    title: 'Image',
    type: 'image',
    fields: [
      {
        name: 'alt',
        type: 'string',
        description:
          "Remember to use alt text for people to be able to read what is happening in the image if they are using a screen reader, it's also important for SEO",
        title: 'Alt Text',
      },
    ],
  },

Sanity CMS development. AI-assisted Sanity development, schema generation, and developer workflow optimization.

Sanity Preferred agency partner

I guarantee you, at least 50% of the fields you've just read, you repeat again and again. So guess what? It makes perfect sense to standardise your description text for each of them. We've started with our most common components but I could very much see this list expanding as we add future components consistently.

Inspiration for the post

Taureen Work tweet that inspired us to write this up. Cheers buddy!

Thanks @taureen.work (opens in new tab) for the inspiration for this blog post. It's been something we've wanted to write about for a while as we've been using it fairly consistently in-house. Tell us how you get on with Cursor, we've got no shares in the tool, but we'd genuinely like to know for the developer experience of Sanity in general.

We're going to keep stalking the Sanity twitter (I'm not going to call it X), and if we find any more insightful comments, we're definitely going to give our two cents.

If you want to take AI-assisted development further than prompt engineering, we build agentic workflows that automate entire development and content pipelines. And if you need a hand getting your Sanity project set up properly in the first place, we can help with that too.

Frequently asked questions

How do I set up Cursor for Sanity development?
We recommend three things: index all of Sanity's documentation so you can reference @sanity in a prompt, paste our schema conventions into Cursor's Rules for AI, and turn on the Copilot++ beta. Adjust the rules if you are not using Sanity, Tailwind and Next.js.
What should go in Cursor's Rules for AI for Sanity schema?
Tell it to use Tailwind when the codebase does, to write functional React, and to always include name, title, description and type on every schema field, with the description written for a non-technical user and placed above type. We include template fields for eyebrow, title, portable text, buttons and images.
Why add a description to every Sanity schema field?
Clients and marketers rarely use a CMS the way the developer assumed, because developers are usually buried in documentation. A description on each core field gives editors context, and even an imperfect one is a big improvement on a blank field.
What order should properties go in a Sanity schema field?
Title, name, description, type, then validation and options. We recommend the first four on every schema because they help contextualise each field.
Which Sanity fields are worth templating for AI generation?
The ones you repeat constantly: eyebrow, title, an isHeadingOne toggle, Portable Text, a buttons array and an image with alt text. We reckon at least half of those fields get repeated again and again, so standardising their description text makes sense.
Does indexing Sanity's docs in Cursor actually help?
In our experience, yes. Indexed documentation makes Cursor more contextually accurate for Sanity work and lets you reference @sanity inside a prompt when you want to solve something specific to the CMS.
Is Copilot++ worth turning on in Cursor?
It was rough when first released but now gives useful code improvement suggestions for free, so we advise enabling it.

About the author

Jono Alford

Founder of Roboto Studio, specializing in headless CMS implementations with Sanity and Next.js. A Sanity Pioneer and first-cohort Sanity Community Ambassador, focused on editorial experiences that help teams ship faster.



Related posts





Related videos





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.