Shared objects

Shared objects are reusable schema types in the Studio. Blocks that need a call-to-action or other shared fields use these. Each object has a Schema (Studio) and a UI component that consumes data from Sanity types. Select an object below.

Schema (Studio)

The CTA object defines the schema for call-to-action fields (text, link, variant). Include it in your schema and export it according to your project’s structure.

schema-types/objects/cta.ts
import { defineField, defineType } from 'sanity'

// Shared object. Used by blocks that have CTA (e.g. grid-two-columns).
export const cta = defineType({
  name: 'cta',
  title: 'CTA',
  type: 'object',
  fields: [
    defineField({
      name: 'ctaEnabled',
      title: 'Enable CTA',
      type: 'boolean',
      description: 'Enable or disable the call to action button',
      initialValue: false,
    }),
    defineField({
      name: 'text',
      title: 'Text',
      type: 'string',
      hidden: ({ parent }) => parent?.ctaEnabled === false,
    }),
    defineField({
      name: 'link',
      title: 'Link',
      type: 'string',
      hidden: ({ parent }) => parent?.ctaEnabled === false,
    }),
    defineField({
      name: 'variant',
      title: 'Variant',
      type: 'string',
      options: {
        list: [
          { title: 'Default', value: 'default' },
          { title: 'Secondary', value: 'secondary' },
          { title: 'Outline', value: 'outline' },
          { title: 'Ghost', value: 'ghost' },
          { title: 'Link', value: 'link' },
        ],
        layout: 'radio',
      },
      initialValue: 'default',
      hidden: ({ parent }) => parent?.ctaEnabled === false,
    }),
  ],
})

CTA component (UI)

Component that consumes CtaType from your generated types (e.g. sanity.types.ts). Use this in blocks that have a CTA field from Sanity.

import Link from 'next/link'

import { cn } from '@/lib/utils'
import { Cta as CtaType } from '@/sanity.types'

import { Button } from '../ui/button'

export function Cta({
  cta,
  className,
}: Readonly<{ cta: CtaType; className?: string }>) {
  if (!cta?.ctaEnabled) {
    return null
  }

  return (
    <Button
      className={cn('w-fit rounded-full px-5', className)}
      variant={cta?.variant ?? 'default'}
      asChild
    >
      <Link
        href={cta?.link ?? ''}
        target={cta?.link ? '_blank' : '_self'}
        rel={cta?.link ? 'noopener noreferrer' : undefined}
        aria-label={cta?.text}
      >
        {cta.text}
        {cta?.link && (
          <span className="sr-only">{`${cta?.text} (opens in new tab)`}</span>
        )}
      </Link>
    </Button>
  )
}