Creating a flexible content module with different blocks using arrays in Sanity.io.

22 replies
Last updated: Jul 14, 2020
Hey, how would I go about creating a an array where u chose between a number of objects... basically I want to create a "flexible content" module, with diff blocks to choose from, preferebly not using a rich text editor.
AI Update

You're looking for an array of objects approach - this is exactly what Sanity calls a "page builder" or "flexible content" pattern! It's a super common setup and doesn't require a rich text editor at all.

Here's how to set it up:

Basic Structure

Create an array field with multiple object types that editors can choose from. Here's a simple example:

{
  name: 'content',
  type: 'array',
  title: 'Page Content',
  of: [
    {
      name: 'hero',
      type: 'object',
      title: 'Hero Section',
      fields: [
        { name: 'heading', type: 'string' },
        { name: 'tagline', type: 'text' },
        { name: 'image', type: 'image' }
      ]
    },
    {
      name: 'textBlock',
      type: 'object',
      title: 'Text Block',
      fields: [
        { name: 'title', type: 'string' },
        { name: 'content', type: 'text' }
      ]
    },
    {
      name: 'gallery',
      type: 'object',
      title: 'Image Gallery',
      fields: [
        { name: 'images', type: 'array', of: [{ type: 'image' }] }
      ]
    }
  ]
}

With TypeScript

If you're using TypeScript, use defineField and defineArrayMember for better type safety:

defineField({
  name: 'content',
  type: 'array',
  title: 'Page Content',
  of: [
    defineArrayMember({
      name: 'hero',
      type: 'object',
      title: 'Hero Section',
      fields: [
        defineField({ name: 'heading', type: 'string' }),
        defineField({ name: 'tagline', type: 'text' }),
        defineField({ name: 'image', type: 'image' })
      ]
    }),
    defineArrayMember({
      name: 'textBlock',
      type: 'object',
      title: 'Text Block',
      fields: [
        defineField({ name: 'title', type: 'string' }),
        defineField({ name: 'content', type: 'text' })
      ]
    })
  ]
})

Key Benefits

This approach gives you:

  • Drag-and-drop reordering of blocks
  • Multiple block types to choose from in a dropdown
  • Copy/paste support for entire blocks or individual items
  • Structured data that's easy to query and render

Making It Better

You can enhance the editing experience by adding custom previews to your blocks so editors can see what each block contains without opening it:

{
  name: 'hero',
  type: 'object',
  preview: {
    select: {
      title: 'heading',
      media: 'image'
    }
  },
  fields: [...]
}

Sanity actually has a full course on page building that covers this pattern in depth, including best practices and advanced techniques. The core concept is that at its fundamental level, a page builder is just an array of objects - exactly what you're describing!

like a page builder?
yeh pretty much, not sure if u have tried but comparable to ACF flexible content for WP, or Matrix fields for Craft CMS
i would make each of your "options" an object component
and setup an array in your document that uses those objects
yeah, ok... i've done this a few times in sanity
something like this
yeh exactly
yeah, so thats just the
array
type
So would it just be adding more obejcts to this?
    {
      title: 'Images',
      name: 'images',
      type: 'array',
      of: [{
        type: 'object',
        fields: [
          { name: 'image', type: 'image', title: 'Image' },
          { name: 'w', type: 'string', title: 'Width' },
          { name: 'o', type: 'string', title: 'Offset' },
          { name: 'effect', type: 'string', title: 'Effect' },
        ]
      }]
    }
are they all part of the "Images" object?
yeh well images would be "flexible content" or someting
so what i've done is built an object called
page builder
and then just dropped in the components i want to use in it
here's the code for the builder
export default {
  title: 'Component Builder',
  name: 'pageBuilder',
  type: 'array',
  of: [
    {
      type: 'copyBlock'
    },
    {
      type: 'inlineImage'
    },
    {
      type: 'video'
    },
    {
      type: 'grid'
    },
    {
      type: 'contentGrid'
    },
    {
      type: 'accordion'
    },
    {
      type: 'mondrian'
    },
    {
      type: 'wonderfulThings'
    },
    {
      type: 'specialComponents'
    },
    {
      title: 'Custom Link',
      type: 'specialLink'
    }
  ],
}
and then in my document (called Page in this case) i just add the builder in
add it as a field, like so

{
      title: 'Page Builder',
      name: 'componentList',
      type: 'pageBuilder'
    },
then in studio when i choose one from teh array its pops up the appropriate input fields
dope, great. this is very helpful👍
looks like this with a few items added
and then you can drag/drop to re-order as needed
great, worked fine:) thx a lot

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?