Create an Array With Two Types - Mixing Primitive Types

22 replies
Last updated: Jan 29, 2021
I just encountered this error when trying to create an array with two types. Is this not possible, or am I doing something wrong? 😬
AI Update

Arrays with multiple types are absolutely possible in Sanity - in fact, they're one of its core features! Without seeing your specific error message, here are the most common issues people run into:

The correct way to define arrays with multiple types:

defineField({
  name: 'myArray',
  type: 'array',
  of: [
    {type: 'block'},  // Standard rich text
    {type: 'image'},  // Built-in image type
    {type: 'myCustomObject'},  // Your custom object
  ]
})

Common problems that cause errors:

  1. Missing the of property entirely - Arrays require an of property that defines what types can be included. If you're seeing an error about an invalid or missing "of" property, make sure you have this structure.

  2. Missing type definitions - If you reference a custom type like {type: 'myCustomObject'}, that type must be defined somewhere in your schema:

export const myCustomObject = defineType({
  name: 'myCustomObject',
  type: 'object',
  fields: [
    defineField({
      name: 'title',
      type: 'string'
    })
  ]
})
  1. Inline objects without a name - If you're defining an object directly within the array, you must give it a name:
// ❌ This will error
of: [
  {
    type: 'object',
    fields: [...]
  }
]

// ✅ This works
of: [
  {
    name: 'myInlineObject',
    type: 'object',
    fields: [...]
  }
]
  1. Type name conflicts - Make sure your array member type names don't conflict with built-in types or other global type names in your schema.

  2. Schema not imported - Ensure your custom types are imported and included in your main schema configuration file.

You can also use the defineArrayMember helper for better TypeScript support:

of: [
  defineArrayMember({type: 'block'}),
  defineArrayMember({type: 'image'}),
  defineArrayMember({
    name: 'customBlock',
    type: 'object',
    fields: [...]
  })
]

If you share the specific error message you're seeing, I can give you more targeted help! Common errors include "invalid 'of' property" or "unknown type" messages.

It's a bit subtle, but
image
 is an actually an object type, and you can't mix primitive types (like numbers and strings) with object types. That means that you have to put your
string
 inside of an object. So:
of: [ { type: 'object', fields: [{type: 'string', name: 'text'}]}, { type: 'image' }]

Ohh, of course! I did know about that rule, I just didn't think of the fact that image is not a primitive type. Thanks a lot, Knut! 💕
Not at all! I think this is a pretty common stumbling block tbh.
If you don't mind, I have another question.. Or well, could you assist me in how to write the query for this, to be able to use a referenced image and get the text, too? My code right now looks something like this, but the browser doesn't like it..
"test_steps" : test_steps[] {"image":asset->{tags,url}}.image
Ah, but you can also do:
{
  name: 'gallery',
  type: 'array',
  of: [
  {
    type: 'image',
    fields: [
      {
        name: 'alt',
        type: 'string',
      },
      {
        name: 'caption',
        type: 'string',
      }
    ]
  }
]

🙂
If I get what you're trying to do
Hmm, I'm building a site for a girl who writes recipes, as well as a lot of other things, and right now I'm building her recipe-page. This part is for the step-by-step when cooking the recipe, in which I want her to be able to put images in between the steps.. When typing this I'm wondering if maybe it would be easier just to build that functionality myself in the frontend instead, since it's a lot easier for her to just enter all steps in text-form without complicating it.. hmm.
My wish was to query for the entire array that consists of both text-parts and images..
Ah! Get ya. But Sanity is perfect for recipes 🙂 And you can totally do that,
(two seconds)
I think I got it 🙂 Or well, this one worked..
"test_steps" : test_steps[] {"image":asset->{tags,url}, "text": text},
It's just that the ui is looking a bit easier when just adding text to an array, rather than having to choose and entering each step into a modal box. 🙂
Ah, got ya
I really, really appreciate your help. I can't even begin to describe how amazed I am by your company and your level of service and kindness 🙂
That's great to hear!
Btw. I know that
user S
has built a pretty cool recipe blog, He might have some insights too https://www.sanity.io/projects/merearchive
Oh, I will definitely check that out! 😊
Yeah you can see how I structured the recipe part. I didn't put too much effort to make a custom input form for that, and just used the built-in forms even they might be a bit verbose in my case. (The only person using it is my wife and she's now used to it 🙂)
Wow, that page of yours looks really good! 🌟 Very inspirational to see how you worked with the studio! I'm working on my final project for my 6 months frontend bootcamp, and so far it looks like this (all the other food-pages looks a bit off since I'm trying out different solutions for the steps 😅):
https://carolineborg.netlify.app/food/glutenfria-scones-med-havregryn
Wow I love the design, photos, fonts and everything!In my project my wife and I wanted to provide recipes for both people in USA and those that are not, because Korean food seems to become more popular in USA and they need different measuring units
🙂 So I went down the rabbit hole to provide recipes with unit converter. Otherwise, it could've been a simple array of strings.
Ohh I just saw that! Amazing 🙂 Did you solve the convert-functionality in the frontend, or do you run some sort of function in the backend?
The converter is on the frontend :)

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?