πŸ—“οΈ Everything *[NYC] is back. A free gathering for AI builders. Sept 9 β†’

Sanity Seo Plugin

The sanity-plugin-seo Plugin is designed to simplify the process of generating SEO fields for various types of content.

By Bhargav Patel

Install command

npm i sanity-plugin-seo

Sanity Plugin SEO

⚑ Sanity Plugin SEO

npm version npm downloads TypeScript

Sanity Studio Compatibility:

Sanity V3 Sanity V4 Sanity V5

Framework Support:

Next.js Astro Vue

The complete SEO toolkit for Sanity Studio. Empower your team with live SEO scoring, AI-powered content suggestions, team workflows, and comprehensive structured data support.

Production-Ready: Free and AI tiers live. Pro features coming soon with team workflows, bulk optimization, and schema management.

Demo Video

Demo

Complete Feature Set

Everything from basic SEO optimization to advanced team workflows.

FeatureFreeAIπŸ”œ Pro
Live SEO Score (0–100)βœ…βœ…β€”
GEO Checklist (AI Overview readiness)βœ…βœ…β€”
Meta Tags Preview + HTML snippetβœ…βœ…β€”
Social Preview Cards (X, Facebook, LinkedIn, WhatsApp)βœ…βœ…β€”
Focus Keyword trackingβœ…βœ…β€”
Robots Meta (noindex, nofollow, noarchive…)βœ…βœ…β€”
hreflang / multi-language targetingβœ…βœ…β€”
Open Graph & Twitter/X card fieldsβœ…βœ…β€”
Additional meta tagsβœ…βœ…β€”
Frontend integration guides (Next.js, Astro, Vue)βœ…βœ…β€”
Readability scoreβœ…βœ…β€”
AI Keyword Suggestionsβ€”βœ…β€”
AI Meta Title & Description generationβ€”βœ…β€”
SERP Preview (desktop + mobile)β€”β€”πŸ”œ
Schema.org Wizard (30+ structured data types)β€”β€”πŸ”œ
Live JSON-LD previewβ€”β€”πŸ”œ
SEO Health Dashboard (site-wide scores)β€”β€”πŸ”œ
SEO Optimizer β€” inline bulk edit, type filter, CSV import/exportβ€”β€”πŸ”œ
Bulk Open Graph syncβ€”β€”πŸ”œ
Advanced Validation (5 checks + auto-fix)β€”β€”πŸ”œ
Team Workflow (Draft β†’ Review β†’ Approved)β€”β€”πŸ”œ
Workflow Dashboard (site-wide status tracking)β€”β€”πŸ”œ
Duplicate meta title detectionβ€”β€”πŸ”œ
AI Bulk SEO Generationβ€”β€”πŸ”œ

What Each Tier Includes

🎁 Free β€” Essential SEO tools built-in. Start optimizing immediately.

πŸ€– AI β€” Add AI-powered suggestions. Choose from OpenAI, Anthropic, or Groq (free tier available).

πŸ‘₯ Pro β€” Coming Soon. Team workflows, bulk optimization, advanced analytics, and schema management for enterprise teams.

Table of Contents

Quick Start

1. Install the plugin

npm install sanity-plugin-seo

Or with yarn/pnpm:

yarn add sanity-plugin-seo    # or
pnpm add sanity-plugin-seo

Compatibility: Sanity Studio v3, v4, and v5

2. Configure in Sanity Studio

Option A: Free features only

// sanity.config.ts
import { defineConfig } from "sanity";
import { seoMetaFields } from "sanity-plugin-seo";

export default defineConfig({
  plugins: [seoMetaFields()],
});

Option B: With AI (OpenAI, Anthropic, or Groq)

Add AI-powered suggestions for meta titles, descriptions, and keywords.

import { defineConfig } from "sanity";
import { seoMetaFields } from "sanity-plugin-seo";

export default defineConfig({
  plugins: [
    seoMetaFields({
      aiFeature: {
        provider: "openai", // 'openai' | 'anthropic' | 'groq'
        apiKey: process.env.SANITY_STUDIO_OPENAI_KEY!,
        model: "gpt-4o-mini", // optional
      },
      bodyFields: ["body"], // single field β€” or pass multiple, see bodyFields docs below
      slugField: "slug",
    }),
  ],
});

Option C: With Pro license (Coming Soon)

Unlock team workflows, bulk optimization, and advanced schema management.

seoMetaFields({
  proFeature: process.env.SANITY_STUDIO_SEO_LICENSE!,
  projectId: process.env.SANITY_STUDIO_PROJECT_ID!,
});
Env variableValue
SANITY_STUDIO_SEO_LICENSEYour license key from Lemon Squeezy
SANITY_STUDIO_PROJECT_IDYour Sanity project ID (find it in sanity.json or manage.sanity.io)

Sanity Studio env vars must be prefixed with SANITY_STUDIO_ to be included in the browser bundle.

Complete Configuration

import { defineConfig } from "sanity";
import { seoMetaFields } from "sanity-plugin-seo";

export default defineConfig({
  plugins: [
    seoMetaFields({
      // AI provider (OpenAI, Anthropic, or Groq)
      aiFeature: {
        provider: "openai", // 'openai' | 'anthropic' | 'groq'
        apiKey: process.env.SANITY_STUDIO_OPENAI_KEY!,
        model: "gpt-4o-mini",
      },
      // Body content fields for AI analysis β€” string, string path, or Sanity path array
      bodyFields: [
        "body",                          // simple field
        "sections[].content",            // array traversal
        ["sections", "columns", "body"], // Sanity native path array
      ],
      slugField: "slug",
      // Show SEO Health + Optimizer in Studio toolbar (default: true)
      dashboard: true,
    }),
  ],
});

3. Add SEO to Your Documents

Add the seoMetaFields type to any document schema in your project:

// schemas/page.ts
export default {
  name: "page",
  type: "document",
  fields: [
    { name: "title", type: "string" },
    { name: "slug", type: "slug", options: { source: "title" } },
    { name: "body", type: "array", of: [{ type: "block" }] },
    { name: "seo", type: "seoMetaFields" },
  ],
};

This adds a fully-featured SEO panel with four tabs:

  • Basic SEO β€” Meta title, description, keywords
  • Social Sharing β€” Open Graph & Twitter cards
  • Advanced β€” Robots meta, hreflang, custom tags
  • Schema.org β€” 30+ structured data types (Pro)

Configuration Options

All options are optional. The plugin works great with zero configuration.

OptionTypeDefaultDescription
Content Fields
bodyFieldstring'body'Single body field name (legacy β€” prefer bodyFields)
bodyFieldsArray<string | string[]>β€”One or more body field paths; each item is a string path ('sections[].content') or a Sanity path array (['sections','content'])
slugFieldstring'slug'Slug field for URL preview in SERP
AI Features
aiFeatureobjectβ€”Enable AI keyword and content suggestions
aiFeature.provider'openai' | 'anthropic' | 'groq'β€”AI provider (OpenAI/Anthropic/Groq)
aiFeature.apiKeystringβ€”API key from your provider
aiFeature.modelstringprovider defaultModel ID (e.g., gpt-4o-mini, claude-haiku-4-5-20251001)
Pro Features
proFeaturestringβ€”Your Lemon Squeezy license key
projectIdstringβ€”Your Sanity project ID β€” used for seat-binding (required for Pro)
UI
dashboardbooleantrueShow SEO Health & Optimizer in Studio toolbar

Framework Integration Guides

Complete copy-paste guides with GROQ queries, TypeScript types, and JSON-LD helpers are on the docs site.

Next.js

Works with both App Router (generateMetadata) and Pages Router (next-seo). Includes a buildMetadata helper and JSON-LD support.

β†’ Full Next.js guide

Astro

Works with astro-seo or native <head> tags. Includes Sanity client setup and a buildJsonLd helper.

β†’ Full Astro guide

Vue 3 / Nuxt

Works with Nuxt 3 (useHead) and Vue 3 standalone (@unhead/vue). Uses @sanity/client directly β€” no @nuxtjs/sanity needed.

β†’ Full Vue / Nuxt guide

SvelteKit

Works with SvelteKit's +page.server.ts load function and <svelte:head> for meta tags.

β†’ Full SvelteKit guide

GROQ Fragment & Types

Copy and use this GROQ fragment to fetch all SEO fields from your documents:

const pageQuery = groq`*[_type == "page" && slug.current == $slug][0]{
  title,
  seo {
    metaTitle, metaDescription, focusKeyword, seoKeywords,
    nofollowAttributes, robotsMeta,
    metaImage { asset->{ url } },
    openGraph { title, description, siteName, image { asset->{ url } } },
    twitter { cardType, site, creator, handle },
    hreflang[] { locale, url },
    schemaOrg {
      schemaType, name, description, url, author,
      datePublished, dateModified,
      price, priceCurrency, availability,
      ratingValue, ratingCount,
      startDate, endDate, location,
      faqItems[] { question, answer }
    },
    seoStatus, seoReviewNotes
  }
}`;
FieldTypeNotes
metaTitlestringPage title for search engines
metaDescriptionstringPage description
focusKeywordstringPrimary keyword
seoKeywordsstring[]Additional keywords
nofollowAttributesbooleanNoindex toggle
robotsMetastring[]e.g. ['noindex', 'nofollow']
metaImage.asset.urlstringFallback OG/Twitter image
openGraph.titlestringOG title
openGraph.descriptionstringOG description
openGraph.siteNamestringOG site name
openGraph.image.asset.urlstringOG image
twitter.cardTypestringe.g. summary_large_image
twitter.sitestringTwitter @account
twitter.creatorstringTwitter @author
hreflang[].localestringBCP 47 locale code
hreflang[].urlstringAlternate URL for that locale
schemaOrg.schemaTypestringSchema.org type
seoStatusstringdraft | review | approved
seoReviewNotesstringReviewer notes

Body Fields (bodyFields)

bodyFields accepts an array where each item is either a string path or a Sanity path array:

seoMetaFields({
  bodyFields: [
    "body", // simple field
    "excerpt", // plain string or Portable Text
    "sections[].content", // string with '[]. ' array traversal
    "sections[].columns[].body", // nested array traversal
    ["sections", "columns", "content"], // Sanity native path array
  ],
});

Path formats

ItemResolves to
"body"document.body
"sections[].content".content from every item in document.sections
"sections[].columns[].body"nested array traversal
["sections", "columns", "body"]document.sections.columns.body (direct path, no iteration)

Fields are resolved in order β€” earlier fields are higher priority when the AI prompt trims to 2000 characters.

bodyField: "body" (single string) still works and is kept for backwards compatibility. bodyFields takes precedence when both are set.

Free Features

Readability Score

Calculates a Flesch-Kincaid Grade Level for your content and shows it with color-coded feedback directly beneath the body field.

GradeMeaning
1–6Very easy β€” general public
7–8Easy β€” ideal for most blog posts
9–12Average β€” acceptable for technical content
13+Difficult β€” academic/specialist

Green = Grade ≀ 8, Amber = 9–12, Red = 13+.

Pro Features (Coming Soon)

Team workflows, bulk optimization, SERP preview, Schema.org wizard, advanced validation, and site-wide dashboards β€” all in development.

Star the GitHub repo to get notified when Pro launches.

AI Provider Setup

Three AI providers supported. Choose based on your needs and budget.

OpenAI (Paid)

seoMetaFields({
  aiFeature: {
    provider: "openai",
    apiKey: process.env.SANITY_STUDIO_OPENAI_KEY!,
    model: "gpt-4o-mini",
  },
  bodyFields: ["body"],
});

Recommended: gpt-4o-mini (fast), gpt-4o (better quality)

Anthropic (Paid)

seoMetaFields({
  aiFeature: {
    provider: "anthropic",
    apiKey: process.env.SANITY_STUDIO_ANTHROPIC_KEY!,
    model: "claude-haiku-4-5-20251001",
  },
  bodyFields: ["body"],
});

Recommended models: claude-haiku-4-5-20251001 (fast & cheap), claude-sonnet-4-6 (best quality)

Groq (Free)

seoMetaFields({
  aiFeature: {
    provider: "groq",
    apiKey: process.env.SANITY_STUDIO_GROQ_KEY!,
    model: "llama-3.3-70b-versatile",
  },
  bodyFields: ["body"],
});

Free API: Sign up at console.groq.com
Recommended models: llama-3.3-70b-versatile, mixtral-8x7b-32768

⚠️ Security Note: API keys are bundled in the browser. Always use restricted API keys with minimal permissions, and prefix env vars with SANITY_STUDIO_.

Upgrading from v1.3 to v1.4

Good news: No schema migrations needed. All existing SEO fields continue to work. Just update your config.

What Changed

The basic setup works exactly the same:

// v1.3 and v1.4 β€” no changes needed
plugins: [seoMetaFields()];

New in v1.4: AI and Pro features are now available with renamed config keys:

FeatureConfig Key (v1.4)
AI suggestionsaiFeature
Pro licenseproFeature

See AI Provider Setup and Pro License Setup for configuration examples.

New Fields in v1.4

These new schema fields are optional and automatically included:

FieldTypePurpose
focusKeywordstringPrimary target keyword for tracking
robotsMetastring[]Indexing control (noindex, nofollow, noarchive, nosnippet)
hreflangarrayAlternate language/regional URLs
additionalMetaTagsarrayCustom name/content meta tag pairs
schemaOrgobjectSchema.org structured data (Pro feature)
seoStatusstringWorkflow status: draft, review, approved (Pro feature)
seoReviewNotesstringReviewer feedback and notes (Pro feature)

Existing documents work fine without these new fields β€” they're completely optional.

TypeScript Types

interface SeoData {
  metaTitle?: string;
  metaDescription?: string;
  focusKeyword?: string;
  seoKeywords?: string[];
  nofollowAttributes?: boolean;
  robotsMeta?: string[];
  metaImage?: { asset: { url: string } };
  openGraph?: {
    title?: string;
    description?: string;
    siteName?: string;
    image?: { asset: { url: string } };
  };
  twitter?: {
    cardType?: string;
    site?: string;
    creator?: string;
    handle?: string;
  };
  hreflang?: { locale: string; url: string }[];
  schemaOrg?: {
    schemaType?: string;
    name?: string;
    description?: string;
    url?: string;
    author?: string;
    datePublished?: string;
    dateModified?: string;
    price?: string;
    priceCurrency?: string;
    availability?: string;
    ratingValue?: string;
    ratingCount?: string;
    startDate?: string;
    endDate?: string;
    location?: string;
    faqItems?: { question: string; answer: string }[];
  };
  seoStatus?: "draft" | "review" | "approved";
  seoReviewNotes?: string;
}

Support & Community

Creator

Built by Bhargav Patel

License

MIT β€” Free and AI features are open source. Pro coming soon.