62 questions answered
Frequently Asked Questions
Everything you need to know about sanity-plugin-seofields
General
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.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.
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. Paid features require a $20 one-time license per Sanity project. No subscription, ever.
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 unlocks paid features.
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.
Open Graph
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.
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.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
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.
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.
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
Editors can toggle index / noindex, follow / nofollow, translate / notranslate, and image index / noimageindex directives independently per document.
In
generateMetadata(), map the GROQ result to robots: { index: !seo.robots?.noIndex, follow: !seo.robots?.noFollow, notranslate: !!seo.robots?.noTranslate, noimageindex: !!seo.robots?.noImageIndex }. Next.js automatically renders the appropriate <meta name="robots"> tag.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
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.
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.
Pass
showSerpPreview: false in the plugin options: seofields({ showSerpPreview: false }). The preview component is tree-shaken from the bundle when disabled.AI Generation
AI generation can create SEO titles, meta descriptions, focus keywords, keyword suggestions, Open Graph titles and descriptions, and X/Twitter titles and descriptions. The generated text is written back into the normal SEO fields, so editors can review and adjust it before publishing.
The built-in providers are
openai, anthropic, groq, gemini, and ollama. You can also pass a custom baseUrl for OpenAI-compatible APIs such as DeepSeek, xAI Grok, Azure OpenAI, or self-hosted gateways.For production, no. Sanity Studio is a client-side app, so an
apiKey in sanity.config.ts is bundled into browser JavaScript and can be read by anyone with Studio access. Use endpoint with a server-side proxy adapter when the provider key must stay private.The package exports adapters from
sanity-plugin-seofields/server: createNextRouteHandler, createExpressHandler, createNodeHandler, and createFetchHandler. Studio sends the field, extracted content, focus keyword, keywords, and existing metadata to your endpoint; the server calls the AI provider and returns { result: string }.Yes. Set
testMode: true in the ai config to preview the Studio UI and generation flow without a provider key or network request. Test mode returns static demo outputs and is useful for demos, screenshots, and local setup checks.By default it reads the document's
body field. Use ai.content to point at another field, an ordered array of fields such as ['title', 'excerpt', 'body'], or a per-document-type mapping with a default fallback.Each generated field has up to 10 prompt variations. Generic prompts are free. Free industries such as blog, restaurant, travel, ecommerce, education, fitness, hospitality, and nonprofit include 4 free variations and unlock the remaining 6 with a license. Pro industries such as healthcare, pharmacy, finance, realestate, saas, legal, insurance, automotive, and homeServices require a license for their prompt pool.
Yes. Use
customPrompt for one custom prompt on the free tier, or customPrompts for up to 5 generic plus 5 per-industry prompts behind a valid license. Your function receives all extracted document values (content, focusKeyword, keywords, meta, field, industry) and returns the prompt string. Custom prompts replace the built-in pool by default, or set merge: true to mix them in. In proxy (endpoint) mode, set them on the server handler config.No license is needed for generic AI generation or the public prompt pool. A valid root-level
licenseKey unlocks licensed prompt expansion, pro industries, and the full prompt pool for the current Sanity project.Yes. Use the
ollama provider for local models. Ollama mode does not need a hosted provider API key, but the local Ollama service must be available from the environment where generation runs.Yes. The generation pipeline checks target field length, required keyword presence, readability for descriptions, and focus-keyword alignment where possible. You can control retry behavior with
maxRetries and choose whether to keep the first raw response with keepFirstOnValidationFail.Yes. Use
ai.buttonWidth. The default 'full' stretches the Generate button to the field width; 'auto' keeps it left-aligned at normal button width.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.
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.
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.
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.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.
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.
Yes. The SEO Health Dashboard is one of the paid features unlocked by 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
The plugin ships with 39 Schema.org types, including Article, BlogPosting, WebPage, WebSite, Product, FAQPage, HowTo, Event, Person, Organization, LocalBusiness, BreadcrumbList, Recipe, Review, NewsArticle, OpinionNewsArticle, VideoObject, ImageObject, SoftwareApplication, JobPosting, Course, Movie, Book, MusicRecording, MusicAlbum, Service, Brand, Offer, AggregateRating, ContactPoint, PostalAddress, Place, Country, WebApplication, SocialMediaPosting, LegalService, Restaurant, ItemList, and ProfilePage.
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.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.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.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.
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.
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
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.Yes. Each field group accepts a
hidden callback using Sanity's standard conditional-fields API: seofields({ fields: { schemaOrg: { hidden: ({ document }) => document.type !== 'article' } } }).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.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.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
*[_type == "page" && slug.current == $slug][0] {
title,
seo {
title,
description,
canonicalUrl,
openGraph { title, description, image },
twitter { card, image },
robots { noIndex, noFollow, noTranslate, noImageIndex }
}
}Fetch the document server-side and map the fields:
return { title: seo.title, description: seo.description, alternates: { canonical: seo.canonicalUrl }, robots: { index: !seo.robots?.noIndex, follow: !seo.robots?.noFollow, notranslate: !!seo.robots?.noTranslate, noimageindex: !!seo.robots?.noImageIndex }, openGraph: { title: seo.openGraph?.title, images: [ogImageUrl] } }.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().No. If you use
@sanity/document-internationalization, call buildHreflangs(data._translations, { baseUrl }) on the frontend and pass the result to buildSeoMeta({ hreflangs }). In Studio, set hreflang: { autoFill: true } to add a “Sync from translations” button that fills the field from your translation references.Yes. Use
buildLlmsTxt() and docsToLlmsSection() (exported from sanity-plugin-seofields/head and /next) to build an llms.txt from your Sanity content, then serve it from a /llms.txt route or a build step.License & Pricing
The plugin uses an open-core model. All SEO field features are MIT-licensed and always free. Paid features require a $20 USD one-time license per Sanity project. No recurring subscription, ever.
The $20 license gives one Sanity project access to paid features such as SEO Health Dashboard scoring, filtering, export, pagination, compact mode, audit CLI support, pro AI prompt tiers, Publish Gate, and pro GEO checks. Core SEO fields remain free regardless of license status.
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.
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.
Legacy free beta keys are no longer accepted for paid features — you'll need to buy a license to keep using them. The core SEO fields remain free, and the 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.