Skip to main content
seofields
docs

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

FieldTypeRequiredDescription
titlestringMeta title with live character count and 60-char limit indicator.
descriptiontextMeta description with live character count and 160-char limit indicator.
metaImageimageSocial / meta image with hotspot support.
keywordsarray of stringKeyword tags for the page.
canonicalUrlurlCanonical URL to prevent duplicate content issues.
metaAttributesarray of metaAttributeCustom 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:

sanity.config.ts
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:

schemas/internalDoc.ts
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

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:

app/internal/[id]/page.tsx
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:

Custom field labels
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

Was this page helpful?