Skip to main content
seofields

General

What is sanity-plugin-seofields?
sanity-plugin-seofields is a comprehensive SEO management plugin for Sanity Studio (v3/v4/v5). It adds a single seofields object field to any document schema and exposes meta tags, Open Graph, Twitter/X Cards, robots directives, canonical URLs, a live SERP preview, Schema.org structured-data helpers, and a studio-wide SEO Health Dashboard — all with zero-config.
Is it compatible with Sanity Studio v3, v4, and v5?
Yes. The plugin is fully compatible with Sanity Studio v3, v4, and v5. It follows the official Sanity plugin API and does not use any deprecated internals, so it will continue to work across future minor releases.
Is it free to use?
Yes for the core SEO fields. Meta tags, Open Graph, Twitter/X Cards, robots directives, SERP preview, Schema.org helpers, and field-visibility controls are free. The SEO Health Dashboard requires a $20 one-time license per Sanity project. No subscription, ever.
Do I need a license key for basic SEO fields?
No. Meta tags, Open Graph, Twitter/X Cards, robots directives, SERP preview, Schema.org helpers, and field-visibility controls are all free without a license key. A key is only required to unlock the SEO Health Dashboard.
Where do I get a license key?
Visit sanity-plugin-seofields.thehardik.in/get-license, enter your email and Sanity project ID, complete the one-time checkout, and your key will be emailed to you instantly.

Meta Tags

Which meta tag fields does the plugin add?
The plugin adds: SEO Title (recommended ≤ 60 chars), Meta Description (recommended ≤ 160 chars), Keywords for editorial workflows and content audits, and Canonical URL. Each field includes inline character-count guidance and validation helpers. Google does not use the meta keywords tag as a ranking signal.
Are there character limits enforced on meta titles and descriptions?
The plugin provides soft guidance — a live character counter that turns amber at 55 characters and red at 60 for titles (or 150/160 for descriptions). Hard validation is intentionally avoided so editors retain control, but the SERP preview reflects the truncated result Google would show.
How do I output the canonical URL in my frontend?
Query seo.canonicalUrl via GROQ and pass it to <link rel="canonical" href={...} />. In Next.js App Router you can set it inside the metadata.alternates.canonical property returned from generateMetadata().
Can I customise the default fallback for the SEO title?
Yes. In your plugin config you can pass a titleTemplate function that receives the document title and returns a string used when the editor leaves the SEO title blank — e.g. (t) => `${t} | My Site`.

Open Graph

Which Open Graph fields are included?
The plugin includes OG Title, OG Description, OG Image (with Sanity image asset picker), and OG Type (website, article, product, profile, video.movie, etc.). All fields are optional and fall back gracefully to the base meta fields when left empty.
How do I generate the OG image URL in my frontend?
Use imageUrlBuilder from @sanity/image-url: urlFor(doc.seo.ogImage).width(1200).height(630).url(). This returns an optimised CDN URL that Facebook and LinkedIn accept.
What OG types are supported?
The selector covers the most common open-graph types: website, article, book, profile, music.song, music.album, video.movie, video.episode, and product.

Twitter / X Cards

Which Twitter/X Card types are supported?
The plugin supports summary (small square image) and summary_large_image (full-width banner). The card type selector is shown only when a Twitter image is provided, keeping the UI clean for documents that don't need it.
Can I set a separate image for Twitter vs Open Graph?
Yes. The plugin has dedicated Twitter Image and Twitter Card Type fields independent of the OG image. If you leave the Twitter image empty, the OG image is used as a fallback, which is standard practice.
How do I render the Twitter meta tags in Next.js?
Return a twitter object from generateMetadata(): { card: doc.seo.twitterCardType, title: doc.seo.twitterTitle ?? doc.seo.ogTitle, description: doc.seo.twitterDescription, images: [twitterImageUrl] }.

Robots Directives

What robots directives can I control per document?
Editors can toggle index / noindex and follow / nofollow independently, control noarchive and nosnippet, and set a sitemap priority (0.0–1.0) and changefreq value per document.
How do I apply the noindex directive in my Next.js app?
In generateMetadata(), map the GROQ result to robots: { index: doc.seo.index !== false, follow: doc.seo.follow !== false }. Next.js automatically renders the appropriate <meta name="robots"> tag.
Does the plugin generate a sitemap automatically?
The plugin itself does not generate a sitemap file — that belongs in your frontend. It does expose seo.sitemapPriority and seo.changefreq fields so your sitemap generation code can read them via GROQ and include the correct values.

SERP Preview

What does the SERP Preview show?
The SERP Preview renders a realistic Google-style preview that helps editors spot title, URL, and description issues before publishing. Google can rewrite title links and snippets per query/device, so the preview is guidance rather than a guarantee. It updates in real time as editors type.
Is there a social preview too?
Yes. Next to the Google preview there is an Open Graph / social preview card that simulates how the document link will appear when shared on Facebook, LinkedIn, and similar platforms — showing the OG image, title, and description at the correct 1.91:1 aspect ratio.
Can I disable the SERP preview if I don't need it?
Pass showSerpPreview: false in the plugin options: seofields({ showSerpPreview: false }). The preview component is tree-shaken from the bundle when disabled.

SEO Health Dashboard

What is the SEO Health Dashboard?
The Health Dashboard is a studio-wide tool (accessible from the Sanity Studio toolbar) that scores every document on a 100-point scale across six dimensions: meta completeness, Open Graph completeness, robots configuration, SERP title length, description length, and Schema.org coverage.
What factors affect the 100-point SEO score?
Points are allocated roughly as: SEO title present and within length (20 pts), meta description present and within length (20 pts), canonical URL set (10 pts), OG title + image present (15 pts), Twitter card set (10 pts), robots index/follow enabled (10 pts), Schema.org type configured (15 pts). Partial credit is given for fields that exist but exceed recommended limits.
How do I fix issues flagged by the dashboard?
Each row in the dashboard shows a colour-coded score badge and a list of failing checks. Click Fix next to any document to jump directly to that document in the Studio editor. The dashboard re-scores in real time after you save changes.
Can I filter the dashboard by document type or score range?
Yes. The dashboard toolbar includes filters for document type, score range (e.g. show only documents scoring below 50), and a search box for document title. All filters persist across sessions using localStorage so you pick up where you left off.
Does the dashboard support pagination?
Yes. The dashboard paginates results in batches of 25, 50, or 100 rows. A compact mode toggle reduces row height so more documents fit on screen simultaneously.
Can I export the dashboard results?
Yes. Use the Export button in the dashboard toolbar to download results as CSV or JSON. The export respects the active filters, so you can export only the under-performing documents.
Does the dashboard require a license key?
Yes. The SEO Health Dashboard requires a $20 one-time license key tied to your Sanity project ID. Add it to your plugin config: seofields({ licenseKey: 'YOUR_KEY' }). Get a key at /get-license.

Schema.org Structured Data

Which Schema.org types does the plugin support?
The plugin ships with 38 Schema.org types, including Article, BlogPosting, WebPage, WebSite, Product, FAQPage, HowTo, Event, Person, Organization, LocalBusiness, BreadcrumbList, Recipe, Review, NewsArticle, VideoObject, ImageObject, SoftwareApplication, JobPosting, Course, Movie, Book, MusicRecording, MusicAlbum, Service, Brand, Offer, AggregateRating, ContactPoint, PostalAddress, Place, Country, WebApplication, SocialMediaPosting, LegalService, Restaurant, ItemList, and ProfilePage.
How do I add Schema.org fields to my document schema?
Import the helper and add it as a field: import { schemaOrgField } from "sanity-plugin-seofields" then include schemaOrgField() in your fields array. The field renders a type selector and contextual input fields for the chosen Schema.org type.
Does the plugin output JSON-LD automatically?
The plugin stores structured data as plain JSON in your Sanity dataset. It does not inject <script type="application/ld+json"> tags server-side — that is intentionally left to your frontend so you keep full control over rendering and hydration.
How do I render the JSON-LD in Next.js?
Query seo.schemaOrg via GROQ and output: <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(doc.seo.schemaOrg) }} /> inside your page component. For App Router, place it inside the root <head> via a layout or a generateMetadata export.
Does Schema.org guarantee rich results or AI citations?
No. Valid Schema.org JSON-LD improves eligibility for supported rich results and gives search engines and AI answer systems clearer machine-readable context, but it does not guarantee rankings, rich snippets, AI Overview links, or citations. The markup must match visible page content and the page still needs useful, trustworthy content.
Should I use FAQPage and HowTo schema everywhere?
No. Use FAQPage only when the same questions and answers are visible on the page, and use HowTo only for real step-by-step instructions. Over-marking pages with invisible or irrelevant schema can reduce trust and rich-result eligibility.
How do I make Sanity content AI-answer friendly?
Lead each page with a direct answer, use clear question-style headings, keep examples current, show author/source signals, add last-updated dates, link to related docs, and render JSON-LD that matches the visible content. This helps SEO, AEO, and GEO without relying on hidden markup.

Field Visibility

Can I hide fields I don't need?
Yes. Pass a fields config object to the plugin to selectively enable or disable groups: seofields({ fields: { twitter: false, schemaOrg: false } }). Hidden field groups are excluded from the schema entirely, keeping the editor UI lean.
Can I show fields conditionally based on document values?
Yes. Each field group accepts a hidden callback using Sanity's standard conditional-fields API: seofields({ fields: { schemaOrg: { hidden: ({ document }) => document.type !== 'article' } } }).

CLI

Does the plugin include a CLI?
Yes. The package ships a lightweight CLI accessible via npx sanity-plugin-seofields (or the seofields binary after local install). It currently exposes two commands: validate and audit.
What does the validate command do?
Run npx sanity-plugin-seofields validate in your project root. It checks your sanity.config.ts to confirm the plugin is registered correctly, verifies your license key format (if present), and warns about deprecated config options — useful in CI pipelines.
What does the audit command do?
Run npx sanity-plugin-seofields audit --projectId <id> --dataset <name> --token <token>. It fetches every published document that uses the seofields object and outputs a scored report to stdout (or a file with --output report.json) — the same scoring logic as the in-studio dashboard but usable in scripts and CI.

Frontend Integration

What does the GROQ query for SEO fields look like?
*[_type == "page" && slug.current == $slug][0] {
  title,
  "seo": seo {
    metaTitle,
    metaDescription,
    canonicalUrl,
    ogTitle,
    ogDescription,
    ogImage,
    twitterCardType,
    twitterImage,
    index,
    follow,
    schemaOrg
  }
}
How do I use the SEO data in Next.js generateMetadata()?
Fetch the document server-side and map the fields: return { title: seo.metaTitle, description: seo.metaDescription, alternates: { canonical: seo.canonicalUrl }, robots: { index: seo.index, follow: seo.follow }, openGraph: { title: seo.ogTitle, images: [ogImageUrl] } }.
How do I generate a CDN image URL for the OG image?
Install @sanity/image-url and create a builder: import imageUrlBuilder from "@sanity/image-url"; const builder = imageUrlBuilder(client); const urlFor = (source) => builder.image(source); Then call urlFor(seo.ogImage).width(1200).height(630).url().

License & Pricing

What is the pricing model?
The plugin uses an open-core model. All SEO field features are MIT-licensed and always free. The SEO Health Dashboard requires a $20 USD one-time license per Sanity project. No recurring subscription, ever.
What does the dashboard license include?
The $20 dashboard license gives one Sanity project access to SEO Health Dashboard features: scoring, filtering, export, pagination, compact mode, and audit CLI support. Core SEO fields remain free regardless of license status.
How does the license key work technically?
The license key is a signed JWT bound to your Sanity project ID. On startup the plugin verifies the key signature client-side; no network call is made at runtime. Keys do not expire — once issued they remain valid for the lifetime of that project.
Can I use one license key across multiple environments (dev/staging/prod)?
Yes. A key is bound to a Sanity project ID, not a deployment URL. As long as all environments (local, staging, production) connect to the same Sanity project, one key covers all of them.
What happens if I already have an older beta or legacy key?
Legacy free beta keys are no longer accepted for the dashboard — you'll need to buy a license to keep using it. The core SEO fields remain free, and the dashboard license is $20 per Sanity project (or save with an Agency Pack).

Still have a question?

Open an issue on GitHub or check the full documentation.

FAQ — sanity-plugin-seofields