docs
Changelog
All notable changes to sanity-plugin-seofields. Follows Keep a Changelog · Semantic Versioning
+Added~Changed×Fixed−Removed⚑Security!Deprecated
v1.5.5Apr 15, 2026latest+3
+ ✨ Added
+fieldGroups config option — New top-level plugin option that groups SEO fields into tabbed sections (Sanity groups) inside the seoFields object. Editors can switch between tabs like "Meta", "Open Graph", and "Twitter Card" for a cleaner editing experience. Applies universally to every document using type: 'seoFields'.
+SeoFieldGroup type export — New TypeScript interface for defining field groups, exported from the package entry point.
+SeoObjectFieldName type export — Union type of all top-level field names in the seoFields object ('title' | 'description' | 'metaImage' | …), exported for type-safe group configuration.
v1.5.4Apr 15, 2026+2
+ ✨ Added
+baseMeta schema type — New baseMeta object type that groups the core meta fields (title, description, metaImage, keywords, canonicalUrl, metaAttributes) into a single reusable Sanity object, following the same pattern as the existing openGraph and twitter types. This allows using basic meta fields independently outside of the top-level seoFields object.
+baseMetaSchema export — The new baseMeta type is exported from the package entry point as baseMetaSchema for standalone use:
v1.5.3Apr 13, 2026~2·1
~ 🔄 Changed
~buildSeoMeta refactor — Extracted three private helper functions from buildSeoMeta in seoMeta.ts: resolveOgImage, resolveTwitterImage, and buildCustomMetaMap. Logic is unchanged; separation improves readability and testability.
~SeoMetaTags return type — Added explicit React.JSX.Element return type annotation to SeoMetaTags in SeoMetaTags.tsx.
· 🧹 Internal
·Removed unused SeoFields type import from seoMeta.ts.
v1.5.2Apr 3, 2026+4~3
+ ✨ Added
+Export to CSV / JSON — New export buttons in the dashboard controls bar let you download all currently-filtered documents as a .csv or .json file. Controlled via the new export option in healthDashboard config:
+Pagination — The documents table is now paginated. Default page size is 25 and can be switched to 50, 100, or 200 per page. The selected page size persists across sessions via localStorage. Navigation controls show the current page, total pages, and the document range being displayed.
+Compact stats mode — New compactStats option in healthDashboard config (defaults to false). When true, replaces the 6-card stats grid with a single row of inline stat pills, saving vertical space in tighter layouts.
+Persistent filters — The status and type filter dropdown selections are now saved to localStorage and restored automatically on next visit.
~ 🔄 Changed
~Extracted RenderLicenseLoading and RenderLicenseInvalid as standalone components, making the main render path significantly cleaner.
~Moved VALIDATION_ENDPOINT and CACHE_TTL_MS constants to module scope (previously defined inside the component on every render).
~Filter change handlers now reset the table back to page 1 to avoid showing an empty page when the result count changes.
v1.5.1Mar 31, 2026+1
+ ✨ Added
+Theme switcher in SEO Health Dashboard — A three-way light / dark / system toggle is now rendered in the dashboard header (sun, moon, and monitor icons). The selected theme persists across sessions via localStorage. System mode automatically follows the OS prefers-color-scheme preference and updates live when the OS preference changes.
v1.5.0Mar 29, 2026+10
+ ✨ Added
+seofields CLI — A new seofields binary is included with the package. Run commands directly from your terminal with npx seofields <command>.
+seofields create-config — Interactive wizard that scaffolds a seofields.cli.ts or seofields.cli.js config file with your project credentials. No more manual config file creation or copy-pasting required.
+seofields init — Automatically detects your sanity.config.ts/js and injects the seofields() plugin if not already registered. Supports --schema-org flag to also inject schemaOrg().
+seofields config — Update seofields() configuration options directly from the terminal using dotted key flags (e.g. --baseUrl=https://example.com, --healthDashboard.licenseKey=SEOF-…).
+seofields report — Queries your Sanity dataset and prints an SEO health report as a formatted table or summary. Scores each document across title, description, image, keywords, and Open Graph fields.
+seofields export — Exports all documents with SEO fields as JSON or CSV. Useful for audits and spreadsheet analysis.
+seofields doctor — Checks your local setup: verifies seofields() is registered in sanity.config, confirms peer dependencies are installed, and detects your CLI config file.
+seofields.cli.ts config file — Create a seofields.cli.ts (or .js) file using defineSeoCli() to store your project ID, dataset, and token so you never need to pass flags on every command.
+defineSeoCli() helper — Importable from sanity-plugin-seofields/define-cli. Provides full TypeScript types for the CLI config object including showConnectionInfo and types options.
+Random color themes — The CLI banner uses a random accent color on every run, drawn from the plugin's brand color palette.
v1.4.2Mar 28, 2026~3
~ 🔄 Changed
~Sanity v5 compatibility — Added sanity ^5 to peer dependencies. The plugin now officially supports Sanity Studio v3, v4, and v5. No API changes were required — all existing Studio APIs used by the plugin remain unchanged in v5.
~Updated devDependencies to use sanity@^5.0.0 for development and testing.
~Updated README description to reflect v3/v4/v5 support.
v1.4.1Mar 25, 2026×1
× 🐛 Fixed
×IssuesPopover positioning in desk panes — The popover that displays hidden SEO issues now renders at the correct position when using createSeoHealthPane inside a Sanity desk structure. Changed position: absolute to position: fixed so popover coordinates (from getBoundingClientRect(), which are viewport-relative) align correctly regardless of parent container context or scroll state.
v1.4.0Mar 25, 2026+8·1
+ ✨ Added
+schemaOrg() — combined Sanity plugin (all 24 types + the schemaOrg array type)
+schemaOrgArticlePlugin(), schemaOrgFAQPagePlugin(), schemaOrgProductPlugin() … (one per type)
+Individual raw schema definitions: schemaOrgArticle, schemaOrgWebsite, schemaOrgProduct … (24 total, for manual schema.types registration)
+generateSchemaType() — generator utility for building custom Schema.org types
+buildGenericJsonLd() — generic JSON-LD builder
+TypeScript interfaces: SchemaFieldDef, SchemaFieldOption, SchemaTypeDef, SchemaOrgConfig, SchemaOrgCombinedConfig
+SchemaOrgScripts — renders all JSON-LD scripts from a combined schemaOrg array field, automatically dispatching to the correct renderer per _type
+SchemaOrgScript — low-level single script tag renderer
· 🚀 Improved
·SeoHealthTool and SeoHealthDashboard are now lazy-loaded — wrapped in React.lazy() + React.Suspense. The Studio bundle no longer pays the upfront cost of loading the dashboard code until it is actually navigated to, improving initial Studio load time.
v1.3.2Mar 23, 2026+2~6
+ ✨ Added
+Refresh button — a "Refresh" button now appears in the dashboard header. Clicking it re-fetches documents without a full-page loading flash: the button icon spins while the update completes, and the table updates in place. The button is disabled while an initial load or refresh is already in progress.
+Non-string title warning — when a document's title field is not a plain string (e.g. a Portable Text array returned from a custom GROQ query), an amber inline badge is shown in the Title column instead of a broken/empty link. The badge reads *"⚠ title is not a string — use pt::text(title) in query.groq"* with a tooltip explaining the fix.
~ 🔄 Renamed (with backwards-compatible deprecations)
~display: {
~typeColumn: true,
~documentId: false,
~},
~typeLabels: { productDrug: 'Products' },
~docBadge: (doc) => ({ label: doc.status }),
v1.3.1Mar 21, 2026·2
· 🧹 Internal
·Replaced as any type casts in schema index with proper FieldDefinition typing.
·Fixed negated condition in image cross-check logic.
v1.3.0Mar 21, 2026+3·2
+ ✨ Added
+Inline image validation components — five new Sanity Studio input components that render live, colour-coded feedback hints directly below image upload/URL fields. Feedback cross-checks whether all three image types (meta, OG, Twitter) are set, prompting the editor when any are missing.
+Image validation helpers — new utility functions that power the inline components and can also be reused in custom tooling. Each function returns colour-coded feedback messages and performs cross-field image coverage checks.
+Added an isSubImageSet utility that correctly detects whether an OG or Twitter sub-object has an image configured, supporting both asset upload and URL modes.
· 🔧 Changed
·SEO Health Dashboard scoring — OpenGraph and Twitter card scores are now included in the overall score. Added an Image Completeness bonus when all three image types are present, and robots noIndex now contributes to the score when indexing is enabled.
·Image validation components are automatically registered on their respective schema fields — no consumer-side configuration needed; existing installs pick up the inline hints on upgrade.
v1.2.7Mar 19, 2026×1
× 🐛 Fixed
×SeoFieldsInput now exported from sanity-plugin-seofields/next — the type was defined in seoMeta.ts but missing from the /next re-export, making import type { SeoFieldsInput } from 'sanity-plugin-seofields/next' fail at compile time.
v1.2.6Mar 19, 2026·3
· 🔧 Internal
·Migrated build tool from @sanity/pkg-utils to tsup — replaced package.config.ts with tsup.config.ts for a leaner, faster build pipeline.
·Simplified TypeScript configuration — removed separate tsconfig.dist.json and tsconfig.settings.json, consolidating settings into a single tsconfig.json.
·Updated package.json: set "type": "module", added "main" / "module" fields, and expanded the exports map with explicit types, source, import, and require conditions for both entry points.
v1.2.5Mar 18, 2026~2
~ 🔄 Changed
~Cleaned up internal JSDoc and website documentation wording for the sanity-plugin-seofields/next entry point.
~Reverted exports map to flat string values (import/require as plain strings) — @sanity/pkg-utils does not support nested condition objects and rejects the package during build validation.
v1.2.4Mar 18, 2026+3~4
+ ✨ Added
+sanity-plugin-seofields/next entry point — New sub-path export for use in Next.js Server Components and generateMetadata() functions.
+buildSeoMeta(options) — Converts a Sanity SEO object into a structured metadata object compatible with Next.js App Router's Metadata type. Returns title, description, keywords, robots, openGraph, twitter, alternates.canonical, and other (custom meta attributes). Safe to call in RSC / generateMetadata().
+<SeoMetaTags> — Framework-agnostic React component that renders all SEO meta tags as plain React elements (<title>, <meta>, <link rel="canonical">). Designed for Next.js Pages Router <Head>, Nuxt, Remix, or any SSR <head> slot. Also works in Next.js App Router RSC when imported from sanity-plugin-seofields/next.
~ 🔄 Changed
~MetaAttribute.key and MetaAttribute.type are now optional (key?, type?) — previously required, this change aligns the type with real Sanity document shapes where these fields may be absent.
~OpenGraphSettings gains an explicit url?: string field (maps to og:url).
~TwitterCardSettings gains an explicit creator?: string field (maps to twitter:creator).
~SeoFields now includes metaAttributes?: MetaAttribute[] in its type definition (was missing despite being part of the schema).
v1.2.3Mar 12, 2026+1
+ ✨ Added
+structureTool option — New healthDashboard.structureTool option that routes document-title clicks directly to a named Structure tool instead of relying on Sanity's generic intent resolver. Required when you have multiple structure tools and the monitored documents live in a non-default one. Clicking a title navigates to /{basePath}/{structureTool}/intent/edit/id=…;type=…/ directly.
v1.2.2Mar 11, 2026+3
+ ✨ Added
+Desk Structure Pane (createSeoHealthPane) — Embed the SEO Health Dashboard directly inside Sanity Studio's Structure tool.
+Title truncation in split pane — Document titles now truncate with an ellipsis at any pane width. Fixed by propagating min-width: 0 through the full flex ancestor chain and adding a dedicated TitleCell wrapper.
+Stats grid auto-wrapping — The stats bar cards now use repeat(auto-fit, minmax(130px, 1fr)) instead of a fixed 6-column grid. Cards wrap naturally at narrow pane widths and always fill the full available width when there is space.
v1.2.1Mar 10, 2026+1~1
+ ✨ Added
+previewMode — New healthDashboard.previewMode option that loads realistic dummy documents into the SEO Health Dashboard without querying your dataset. Useful for showcasing, documentation screenshots, and testing the dashboard UI before real content exists.
~ 🔄 Changed
~Dynamic type-badge colours — Type badges in the Type column are no longer mapped to a fixed. Colours are now derived at runtime from a 16-colour palette using a deterministic hash of the _type string. This means:
v1.2.0Mar 9, 2026+5~2
+ ✨ Added
+typeLabels — Map raw _type values to human-readable display labels. Applied in both the Type column and the Type filter dropdown; any unmapped type falls back to the raw _type string.
+typeColumnMode — Control how the Type column is rendered.
+titleField — Specify which document field to use as the display title in the dashboard. Supports a single field name for all types, or a per-type map. Unmapped types always fall back to title.
+docBadge — Callback that renders a custom badge inline with the document title. Receives the full document and returns { label, bgColor?, textColor?, fontSize? } or undefined to render nothing.
+content.loadingLicense, content.loadingDocuments, content.noDocuments — Custom text for the three loading/empty states of the dashboard. Grouped under the existing content block so all text-content customisation is in one place.
~ 🔄 Changed
~emptyState removed — The emptyState config block has been removed. Its three keys (loadingLicense, loadingDocuments, noDocuments) are now part of the content block (see above). Migrate by moving the keys under content.
~Meta description threshold unified — The valid meta description length range is now consistently 120–160 characters across both the inline field feedback and the Health Dashboard score. Previously the two checks used different lower bounds.
v1.1.1Mar 8, 2026~3
~ 🔄 Changed
~License validation — differentiated invalid-key UI: Users who supply a licenseKey that fails validation now see a distinct "Invalid License Key" screen (❌) with a message explaining the key is invalid or revoked, rather than the generic upgrade prompt shown when no key is provided at all.
~License validation — no-key prompt improved: When licenseKey is omitted entirely, the lock screen now shows a full sanity.config.ts code snippet demonstrating exactly where to add the key, making first-time setup clearer.
~License validation — manual cache bypass: Added a "Click here" button on the invalid-key screen that clears the sessionStorage cache entry for the current project and immediately re-runs the validation request against the server. This avoids the 1-hour cache window when a user has just updated their key without needing a full page reload.
v1.1.0Mar 7, 2026+1
+ ✨ Added
+SEO Health Dashboard — a new built-in Studio tool (📊 SEO Health Dashboard) that gives a bird's-eye view of SEO completeness across all documents that have an seo field.
v1.0.10Dec 14, 2025+3−1
+ ✨ Added
+Documented the full set of fieldOverrides and fieldVisibility keys in README field configuration guidance.
+Expanded Field Specifications in README to cover canonical URLs, meta attributes, default share images, keywords, Open Graph metadata, Twitter branding updates, and robots toggles now available in Studio.
+Rebuilt schema reference docs listing the available schema factories and their usage examples.
− ❌ Removed
−Removed references to the dist/types entry point and legacy TypeScript import snippets from documentation, clarifying that only the plugin bundle is exported.
v1.0.9Dec 6, 2025+1~4×1
+ ✨ Added
+Exported the FeedbackType helpers for use across validation-driven UI components.
~ 🔄 Changed
~Hardened plugin configuration typings, including the new ValidHiddenFieldKeys guard and stricter fieldOverrides typing.
~Returned explicit SchemaTypeDefinition instances from the schema factories, ensuring config is forwarded while keeping Sanity typings intact.
~Refreshed SEO form inputs to rely on shared feedback types, memoised keyword lookups, and clearer schema option typing.
~Reordered public exports so schema factories are grouped consistently with the plugin entry point.
× 🐛 Fixed
×Ensured config-driven hidden logic reaches nested Open Graph and X image selectors. #2
v1.0.8Oct 15, 2025×1
× 🐛 Fixed
×Fixed incorrect initial value assignment in the SEO preview field schema — the value is now correctly set to an empty string.
v1.0.7Oct 12, 2025·9·3
· Plugin Configuration Interface Updates
·twitterImageType - Missing field key for X image type selection
·twitterImageUrl - Missing field key for X external image URL
·SeoFieldsPluginConfig.seoPreview - Now supports both boolean and object with prefix function
·SeoFieldsPluginConfig.baseUrl - New string option for setting preview base URL
·SeoFieldsPluginConfig.fieldVisibility - Per-document-type field visibility control
·SeoFieldsPluginConfig.defaultHiddenFields - Global field hiding capability
·AllFieldKeys - Union type covering all 27+ field keys across SEO, Open Graph, and Twitter
·FieldVisibilityConfig - Interface for field visibility configuration per document type
·SeoFieldConfig - Interface for customizing field titles and descriptions
· Configuration Usage Examples
·https://your-domain.com/{slugified-prefix}/{document_slug}
·For doc: { \_type: 'page', slug: { current: 'about-us' } }
·For doc: { \_type: 'post', slug: { current: 'hello-world' } }
v1.0.6Oct 8, 2025+7~5·3·1
+ ✨ Added
+Added fieldVisibility configuration option for controlling field visibility per document type
+New FieldVisibilityConfig interface for type-safe field visibility control
+defaultHiddenFields configuration option to globally hide specific fields
+New field keys: SitewideFieldKeys including openGraphSiteName and twitterSite
+Updated AllFieldKeys type to include both SEO and sitewide field keys
+Enhanced field utility functions: isFieldHidden and getFieldHiddenFunction
+Dynamic field visibility based on document type through fieldVisibility configuration
~ 🔄 Changed
~Updated Twitter schema title from "Twitter" to "X (Formerly Twitter)"
~Updated Twitter field titles to reference "X" instead of "Twitter":
~Updated field descriptions to reference "X (formerly Twitter)"
~Enhanced Twitter and OpenGraph schemas to accept configuration parameters
~Added field visibility controls to openGraphSiteName and twitterSite fields using getFieldHiddenFunction
· Technical Improvements
·Refactored schema types to accept and utilize plugin configuration
·Enhanced field utilities with better type safety and configuration support
·Improved plugin architecture with granular field control capabilities
· 🔗 References
·Add field visibility feature and update Twitter branding to X #1 by @crimsonwebteam
v1.0.5Oct 5, 2025+2×1
+ ✨ Added
+Added creator field to Twitter TypeScript type for content creator attribution
+Updated Twitter type to include creator handle field for better Twitter Card support
× 🐛 Fixed
×Fixed missing creator field in Twitter TypeScript type definition
v1.0.4Oct 4, 2025+3
+ ✨ Added
+Added url field to Open Graph schema for canonical URL specification
+Updated OpenGraph TypeScript type to include url field
+Enhanced Open Graph settings with proper URL handling for social media sharing
v1.0.3Sep 24, 2025+5~2
+ ✨ Added
+Enhanced field override examples and documentation
+Support for multiple field override patterns with fieldOverrides configuration
+Improved plugin configuration documentation with real-world usage examples
+Basic configuration example: customize individual field titles and descriptions
+Advanced configuration example: custom meta attributes with field overrides
~ 🔄 Changed
~Refined configuration examples to demonstrate both basic and advanced usage patterns
~Clarified field override behavior for custom meta attributes
v1.0.2Sep 23, 2024+7~2
+ ✨ Added
+Enhanced plugin configuration with customizable field titles and descriptions
+New SeoFieldsPluginConfig interface for type-safe configuration
+fieldOverrides configuration option to customize individual field properties
+Support for customizing all SEO field types: title, description, canonicalUrl, metaImage, keywords
+Full TypeScript support for configuration options
+New SeoField, SeoFieldKeys types exported for advanced usage
+Introduced seoPreview configuration options if wanted to enable/disable the SEO preview feature | default is true.
~ 🔄 Changed
~Plugin now accepts detailed configuration object with field customization
~Enhanced TypeScript type definitions for better developer experience
Was this page helpful?