baseMeta Schema Type
baseMeta is a lightweight Sanity schema type that ships with sanity-plugin-seofields. It includes only the core meta fields — title, description, image, keywords, canonical URL, and custom meta attributes — with no Open Graph or Twitter Card section. Use it when you want minimal SEO fields without the social-sharing overhead.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
title | string | — | Meta title with live character count and 60-char limit indicator. |
description | text | — | Meta description with live character count and 160-char limit indicator. |
metaImage | image | — | Social / meta image with hotspot support. |
keywords | array of string | — | Keyword tags for the page. |
canonicalUrl | url | — | Canonical URL to prevent duplicate content issues. |
metaAttributes | array of metaAttribute | — | Custom key/value meta tag pairs (string or image values). |
When to use baseMeta vs seoFields
Use baseMeta when…
- — You don't need Open Graph or Twitter Cards
- — Internal tools or admin documents
- — Pages that are never shared on social media
- — Keeping the editing UI minimal
Use seoFields when…
- — You need Open Graph for social sharing
- — You need Twitter/X Card metadata
- — You want the SEO preview or GEO Checklist
- — Public-facing pages
Step 1 — Register in sanity.config.ts
Import baseMetaSchema from the main package and add it to the schema.types array in your Sanity config:
import { defineConfig } from 'sanity'
import seofields, { baseMetaSchema } from 'sanity-plugin-seofields'
export default defineConfig({
// ...
plugins: [seofields()],
schema: {
types: [
baseMetaSchema(), // registers the 'baseMeta' object type
],
},
})Step 2 — Add to a document schema
Reference the registered baseMeta type in any document:
import { defineField, defineType } from 'sanity'
export default defineType({
name: 'internalDoc',
title: 'Internal Document',
type: 'document',
fields: [
defineField({ name: 'title', type: 'string' }),
defineField({
name: 'seo',
title: 'SEO',
type: 'baseMeta', // ← uses the registered type
}),
],
})Step 3 — GROQ Query
*[_type == "internalDoc" && _id == $id][0]{
title,
seo {
title,
description,
metaImage { asset-> { url } },
keywords,
canonicalUrl,
metaAttributes[] { _key, key, type, value }
}
}Step 4 — Render in Next.js
Map the queried data to generateMetadata(). Because baseMeta has no OG or Twitter fields, map only what you need:
import type { Metadata } from 'next'
import { sanityFetch } from '@/sanity/lib/live'
import { urlFor } from '@/sanity/lib/image'
export async function generateMetadata(): Promise<Metadata> {
const { data } = await sanityFetch({ query: INTERNAL_DOC_QUERY })
const seo = data?.seo
return {
title: seo?.title,
description: seo?.description,
keywords: seo?.keywords,
alternates: { canonical: seo?.canonicalUrl },
openGraph: seo?.metaImage?.asset
? { images: [{ url: urlFor(seo.metaImage).width(1200).url() }] }
: undefined,
}
}Field overrides
Pass a config object to baseMetaSchema() to customise field titles and descriptions, or to hide fields:
import { baseMetaSchema } from 'sanity-plugin-seofields'
// In schema.types:
baseMetaSchema({
fieldOverrides: {
title: { title: 'Page Title', description: 'Keep under 60 characters.' },
description: { description: 'Keep under 160 characters.' },
},
defaultHiddenFields: ['metaAttributes'], // same options as the main plugin
})Compatibility: baseMeta and seoFields can both be used in the same project on different document types. They share the same metaAttribute and metaTag helper schemas, which are registered by the main seofields() plugin.
Related
- Schema Types — full overview of all schema types the plugin registers
- Configuration — plugin-level config options
- Field Visibility — hide fields per document type
Was this page helpful?