Sanity Field Groups for SEO Fields
Organize SEO field groups in Sanity Studio using Sanity's native groups feature, so editors can switch between Meta, Open Graph, and Twitter Card tabs instead of scrolling through a long field list.
New to the plugin? Start with the Sanity SEO plugin setup guide before configuring field groups.
Quick Start
Add the fieldGroups array to your plugin config. Each entry creates a tab in Studio:
import seofields from 'sanity-plugin-seofields'
export default defineConfig({
plugins: [
seofields({
fieldGroups: [
{
name: 'meta',
title: 'Meta',
default: true,
fields: [
'title',
'description',
'focusKeyword', // target keyword for GEO checks
'metaImage',
'keywords',
'canonicalUrl',
'metaAttributes',
'robots',
'hreflangs', // international SEO
'metaTagsPreview', // live HTML preview
],
},
{
name: 'openGraph',
title: 'Open Graph',
fields: ['openGraph'],
},
{
name: 'twitter',
title: 'Twitter Card',
fields: ['twitter'],
},
{
name: 'geo',
title: 'GEO / AI',
fields: ['geoChecklist'], // AI Overview readiness
},
],
}),
],
})How it works: The plugin maps your fieldGroups config to Sanity's built-in groups and per-field group properties on the seoFields object type. This is a native Studio feature — no custom UI needed.
SeoFieldGroup Interface
Each group object accepts these properties:
| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique identifier for the group (e.g. 'meta', 'openGraph'). |
title | string | Yes | Human-readable label shown on the tab in Studio. |
default | boolean | No | If true, this tab is selected by default when the editor opens the document. Only one group should be default. |
icon | React.ComponentType | No | Optional icon component displayed next to the tab title. |
fields | SeoObjectFieldName[] | Yes | Array of seoFields field names to include in this group. |
Available Field Names
The fields array accepts top-level field names from the seoFields object. Use the SeoObjectFieldName type for type-safe configuration:
titleMeta titledescriptionMeta descriptionmetaImageSocial sharing imagekeywordsMeta keywordscanonicalUrlCanonical URLmetaAttributesCustom meta attributesrobotsRobots directivespreviewSEO preview (if enabled)openGraphOpen Graph fields (nested object)twitterTwitter Card fields (nested object)focusKeywordTarget keyword for GEO checkshreflangsHreflang alternate entriesgeoChecklistGEO / AI Overview readiness checklistmetaTagsPreviewLive HTML meta tags previewTwo-Tab Layout
You can create any number of tabs. Here's a minimal two-tab setup separating basic SEO from social media fields:
seofields({
fieldGroups: [
{
name: 'seo',
title: 'SEO',
default: true,
fields: ['title', 'description', 'metaImage', 'keywords', 'canonicalUrl', 'robots'],
},
{
name: 'social',
title: 'Social Media',
fields: ['openGraph', 'twitter'],
},
],
})TypeScript Support
Both SeoFieldGroup and SeoObjectFieldName are exported from the package for type-safe configuration:
import seofields, {
type SeoFieldGroup,
type SeoObjectFieldName,
} from 'sanity-plugin-seofields'
// SeoObjectFieldName includes all assignable field keys:
// 'title' | 'description' | 'metaImage' | 'keywords' | 'canonicalUrl'
// 'metaAttributes' | 'robots' | 'preview' | 'openGraph' | 'twitter'
// 'focusKeyword' | 'hreflangs' | 'geoChecklist' | 'metaTagsPreview'
const myGroups: SeoFieldGroup[] = [
{ name: 'meta', title: 'Meta', default: true,
fields: ['title', 'description', 'focusKeyword', 'metaImage'] },
{ name: 'og', title: 'Open Graph',
fields: ['openGraph'] },
{ name: 'geo', title: 'GEO / AI',
fields: ['geoChecklist'] },
]
export default defineConfig({
plugins: [seofields({ fieldGroups: myGroups })],
})Tip: Fields not assigned to any group will appear in all tabs. If you want a field to only show on a specific tab, make sure to include it in exactly one group's fields array.
Compatibility: fieldGroups works alongside fieldVisibility, fieldOverrides, and all other plugin options. Hidden fields will remain hidden regardless of group assignment.
Was this page helpful?