July 18, 2026-9min read

Build AI-Powered SEO-Ready Sanity Sites with sanity-plugin-seo

ImageBy SW Habitation
July 18, 2026

A complete guide to adding AI-powered SEO to Sanity Studio: live scoring, AI meta generation via Groq, OpenAI or Anthropic, Open Graph previews, JSON-LD structured data, hreflang, GEO checklist for ChatGPT and Perplexity, and frontend integration for Next.js, Astro, Nuxt, and more.

Sanity Studio is one of the best content editing experiences available but out of the box, SEO is entirely your responsibility. No meta title field, no description limit, no social preview, no score to tell editors whether a page is ready to rank. Every team handles it differently and none of the approaches scale.

sanity-plugin-seo fixes that. One install adds a full SEO panel to every document in your Studio live scoring, keyword analysis, social previews, AI-generated meta, structured data, hreflang, GEO readiness for AI search engines, and more. This guide covers every feature so you know exactly what you are getting and how to configure it.

Installation

Copy Code
1 npm install sanity-plugin-seo

Works with Sanity v3, v4, and v5. Then add it to your sanity.config.ts:

Copy Code
1 2 3 4 5 6 7 8 9 10 import { seoMetaFields } from 'sanity-plugin-seo'; export default defineConfig({ plugins: [ seoMetaFields({ slugField: 'slug', bodyField: 'body', }), ], });

Reload the Studio. Every document type now has an SEO tab.

Live SEO Score

A real-time score ring (0–100) sits at the top of the SEO panel and updates as editors type no save required. The score reflects the overall readiness of the page for search engines based on everything the plugin can inspect at that moment.

What moves the score:

  • Meta title: present, 10–60 characters, contains focus keyword
  • Meta description: present, 100–160 characters, contains focus keyword
  • Focus keyword density in body content (1–3% is ideal)
  • Open Graph image is set
  • Canonical URL is filled in

Editors see a color-coded ring: red is poor, amber is improving, green is ready. Beneath it, each contributing factor is listed so editors know exactly what to fix not just that something is wrong.

Focus Keyword

The focus keyword field drives keyword analysis across every other field. Once set, the plugin checks whether the keyword appears in the meta title, meta description, and body content and at what density. A keyword that appears in the title but not in the body, or appears 12 times and is flagged as stuffed, all shows up in the score breakdown.

This works with the bodyField or bodyFields config you set at plugin initialization. The plugin extracts plain text from your Portable Text body and runs density analysis against it.

Meta Title and Description

Both fields have live character counters with color-coded feedback. Title turns green at 40–60 characters, description at 100–160. Editors see the current count and the ideal range without leaving the field. If AI generation is configured, a generate button sits next to each field.

The meta title and description you set here are separate from the document title. This lets you write a longer H1 for the page while keeping the meta title tighter for search snippets.

Open Graph — Live Social Preview

The Open Graph section gives editors a live preview of how the page will look when shared on Facebook, LinkedIn, and other platforms that read OG tags. Upload an image, set the OG title and description, and the preview card updates in real time next to the fields.

Fields available under Open Graph:

  • OG Title — can differ from meta title for social context
  • OG Description — separate from meta description
  • OG Image — uploaded directly in Studio, recommended 1200×630
  • OG Type — article, website, etc.

The preview renders at the right aspect ratio so what editors see in Studio matches what actually appears on social media.

Twitter / X Card — Live Preview

Separate from Open Graph, the Twitter Card section lets you set a card type (summary or summary_large_image), Twitter-specific title, description, and image. A live preview renders the card exactly as it appears in a tweet or link share on X.

If you leave Twitter fields blank, most platforms fall back to OG tags — but having dedicated Twitter fields gives you per-platform control without any extra code.

JSON-LD Structured Data — Automatic

Structured data (JSON-LD / Schema.org) is what Google uses to generate rich results review stars, FAQ blocks, breadcrumbs, article metadata in search. It is notoriously painful to write manually and even more painful to keep accurate.

sanity-plugin-seo generates it automatically. Based on the document type and the SEO fields the editor has filled in, the plugin produces the correct Schema.org JSON-LD:

  • Blog posts and articles → Article schema with author, datePublished, dateModified
  • Generic pages → WebPage schema with name, description, URL
  • Organization data pulled from site settings if configured

No editor action required it is on the GEO checklist as a passing item the moment the plugin is installed. Your frontend just reads the seoMetaFields.jsonLd field and injects it as a script tag.

Canonical URL

The canonical URL field lets editors specify the preferred version of a URL important when the same content is accessible at multiple paths (pagination, filters, query strings). A missing canonical on pages with URL variants causes Google to split ranking signals across duplicates.

Set the canonical once in Studio, read it in your frontend, and output it as a standard link rel canonical tag. The live score rewards a filled canonical field.

noindex and nofollow Controls

Toggle noindex and nofollow per document directly from the SEO tab. noindex tells Google not to index the page at all useful for thank-you pages, preview links, staging content. nofollow tells Google not to pass link equity through outbound links on the page.

These translate to the standard robots meta tag in your frontend:

Copy Code
1 <meta name="robots" content="noindex, nofollow" />

Hreflang — Multilingual and Multi-Region SEO

If your site serves the same content in multiple languages or to region-specific audiences (en-US vs en-GB vs fr-FR), hreflang tags tell Google which URL to serve to which user. Getting these wrong or missing them entirely causes Google to pick the wrong language version, suppresses rankings in targeted regions, and can trigger duplicate content flags.

The plugin gives you an hreflang manager in the SEO tab. Add entries with locale codes and corresponding URLs. The stored data maps directly to the HTML link tags your frontend outputs:

Copy Code
1 2 <link rel="alternate" hreflang="en-US" href="https://yoursite.com/en-us/page" /> <link rel="alternate" hreflang="fr-FR" href="https://yoursite.com/fr/page" />

AI Meta Generation

Connect an AI provider and a Generate button appears next to the meta title and description fields. The plugin reads your document body content, sends it to the AI with instructions to write an SEO-optimised title and description at the correct character lengths, and fills the fields. Editors review and adjust they are not writing from scratch.

Three providers are supported:

Groq (Free Tier Available)

Groq offers a generous free tier llama-3.3-70b-versatile is fast, capable, and costs nothing at typical content volumes. Sign up at console.groq.com, copy the API key, add three lines of config:

Copy Code
1 2 3 4 5 6 7 8 9 seoMetaFields({ aiFeature: { provider: 'groq', apiKey: process.env.SANITY_STUDIO_GROQ_KEY, model: 'llama-3.3-70b-versatile', }, slugField: 'slug', bodyField: 'body', })

OpenAI

gpt-4o-mini costs roughly $2–5 per month at normal editorial volumes. Get a key from platform.openai.com:

Copy Code
1 2 3 4 5 6 7 8 9 seoMetaFields({ aiFeature: { provider: 'openai', apiKey: process.env.SANITY_STUDIO_OPENAI_KEY, model: 'gpt-4o-mini', }, slugField: 'slug', bodyField: 'body', })

Anthropic

claude-haiku-4-5 runs at roughly $1–3 per month. Get a key from console.anthropic.com:

Copy Code
1 2 3 4 5 6 7 8 9 seoMetaFields({ aiFeature: { provider: 'anthropic', apiKey: process.env.SANITY_STUDIO_ANTHROPIC_KEY, model: 'claude-haiku-4-5-20251001', }, slugField: 'slug', bodyField: 'body', })

All API keys go in environment variables prefixed with SANITY_STUDIO_ so they are available in the browser Studio without being exposed in your frontend.

bodyFields — AI That Reads Your Whole Page

Most Sanity projects built with a page builder do not have a single body field. Content lives in sections arrays, nested content objects, column layouts sometimes three or four levels deep. The standard bodyField config only reads one field. bodyFields handles complex structures.

Pass an array of paths:

Copy Code
1 2 3 4 5 6 7 8 9 seoMetaFields({ bodyFields: [ 'body', 'sections[].content', 'columns[].text', 'hero.description', ], slugField: 'slug', })

The plugin reads all of them, merges the text, and passes the combined content to the AI provider and to the keyword density analyser. This means the focus keyword analysis and AI generation both see the full page not just one fragment of it.

For deeply nested structures you can also pass Sanity native path arrays:

Copy Code
1 2 3 4 bodyFields: [ ['sections', 0, 'content'], ['pageBuilder', '_type', 'textBlock', 'text'], ]

GEO Checklist — Optimising for AI Search Engines

GEO stands for Generative Engine Optimization. It is the practice of structuring content so that AI-powered search engines ChatGPT, Perplexity, Google AI Overviews, Bing Copilot can parse, quote, and cite it. These tools do not just link to pages; they extract and reproduce specific passages. If your content is not structured correctly, you will not appear in AI-generated answers even when you rank well in traditional search.

The plugin adds a 5-point GEO checklist that updates live in the SEO panel. Here is what each check does:

1. Structured Data Configured

AI crawlers consume structured data to understand what type of content a page contains and who authored it. The plugin generates JSON-LD automatically this check passes the moment the plugin is installed with no action required from editors.

2. Description Is 100–160 Characters

AI summarisation tools read meta descriptions as the primary summary signal. A description shorter than 100 characters gives them too little to work with. Longer than 160 and it gets truncated. The sweet spot is 120–150 enough to be a complete, quotable summary. This check enforces that range.

3. Open Graph Image Is Set

When AI tools cite a page in a response, they often pull the OG image as a visual anchor. Pages without an OG image get cited less frequently and when they are, they appear as text-only, which reduces click-through. This check ensures every page has an image set.

4. Focus Keyword in Title and Description

AI search engines rank pages for relevance the same way traditional search does by matching the user's query to page signals. A keyword in both the title and description is the clearest possible relevance signal. This check verifies both are present simultaneously.

5. Open Graph Fully Filled In

Title, description, and image all set in the OG section. Incomplete OG data means AI crawlers fall back to guessing page context from body text which is less accurate and less likely to produce a usable citation. This check requires all three fields to be filled.

Score 5/5 on the GEO checklist and your page is structured correctly for AI citation. Checks 1 and 5 are effectively automatic once structured data is enabled and OG is filled in which most editors do anyway for social sharing. The checklist surfaces the gaps they might otherwise miss.

Reading SEO Data in Your Frontend

The plugin stores everything in a seoMetaFields object on each document. Query it with GROQ and pass it into your framework's head management:

Next.js App Router

Copy Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 export async function generateMetadata({ params }) { const post = await client.fetch(query, { slug: params.slug }); const seo = post.seoMetaFields; return { title: seo?.metaTitle, description: seo?.metaDescription, keywords: seo?.focusKeyword, robots: { index: !seo?.noindex, follow: !seo?.nofollow, }, alternates: { canonical: seo?.canonicalUrl, languages: Object.fromEntries( (seo?.hreflang || []).map(h => [h.locale, h.url]) ), }, openGraph: { title: seo?.ogTitle, description: seo?.ogDescription, images: [seo?.ogImage?.asset?.url], }, twitter: { card: seo?.twitterCard, title: seo?.twitterTitle, description: seo?.twitterDescription, images: [seo?.twitterImage?.asset?.url], }, }; }

Astro

Copy Code
1 2 3 4 5 6 7 8 9 const { seoMetaFields: seo } = Astro.props; --- <title>{seo.metaTitle}</title> <meta name="description" content={seo.metaDescription} /> <link rel="canonical" href={seo.canonicalUrl} /> <meta property="og:title" content={seo.ogTitle} /> <meta property="og:description" content={seo.ogDescription} /> <meta property="og:image" content={seo.ogImage?.asset?.url} /> <script type="application/ld+json" set:html={JSON.stringify(seo.jsonLd)} />

Nuxt

Copy Code
1 2 3 4 5 6 7 8 9 10 11 const { data: post } = await useFetch('/api/post', { query: { slug: route.params.slug } }); const seo = post.value.seoMetaFields; useSeoMeta({ title: seo.metaTitle, description: seo.metaDescription, ogTitle: seo.ogTitle, ogDescription: seo.ogDescription, ogImage: seo.ogImage?.asset?.url, twitterCard: seo.twitterCard, });

SvelteKit

Copy Code
1 2 3 4 5 6 7 8 9 10 11 12 // +page.server.ts export const load = async ({ params }) => { const post = await client.fetch(query, { slug: params.slug }); return { seo: post.seoMetaFields }; }; // +page.svelte <svelte:head> <title>{seo.metaTitle}</title> <meta name="description" content={seo.metaDescription} /> <link rel="canonical" href={seo.canonicalUrl} /> </svelte:head>

Sanity Version Compatibility

sanity-plugin-seo works with Sanity v3, v4, and v5. The plugin API follows Sanity's plugin convention it is a standard definePlugin export with no monkey-patching, so upgrades between Sanity major versions do not break it. Install, configure once, update when you update Sanity.

Where to Find It

Package on npm. Full setup docs, AI config, and per-framework examples in the documentation. Feature overview and pricing (all free) on the plugin site. Source under MIT on GitHub. We use it across every project at SW Habitation.

FAQ's

Is sanity-plugin-seo free?

Which Sanity versions does it support?

Do I need an AI API key to use the plugin?

Which AI providers are supported?

Does it work with Next.js App Router?

What is GEO and why does the plugin include a checklist for it?

Read More

Conclusion

sanity-plugin-seo covers everything SEO requires in a content-managed site, from the basics editors need every day (meta title, description, Open Graph, score feedback) to the technical layer developers usually have to wire up manually (JSON-LD, hreflang, canonical, noindex) and the emerging layer that most plugins have not caught up with yet (GEO readiness for ChatGPT, Perplexity, and Google AI Overviews).

=> Install once, configure in three lines.

=> Editors get live feedback without leaving Studio.

=> AI generates your meta, editors review, not write.

=> GEO checklist keeps every page ready for AI search citation.

=> Frontend reads one clean seoMetaFields object. Works in Next.js, Astro, Nuxt, SvelteKit, and Remix.

Free and MIT licensed. No Pro tier to unlock, every feature ships on install.

SW Habitation
Founder & CEO
Preview Pdf

Next blog that you can read...

September 1, 2025-2min read
Why CSS Transitions Slow Down Your Website and How to Fix It ?
ImageBy SW Habitation
August 22, 2025-2min read
What is Blitz.js? Features, Pros, Cons, Installation & FAQs
ImageBy SW Habitation
August 22, 2025-2min read
What is Redwood.js? Features, Pros, Cons, Installation & FAQs
ImageBy SW Habitation