Can you have multiple "type: reference" entries in an array in Sanity.io?

12 replies
Last updated: Dec 31, 2020
Is it possible to have a
type: array
, of more than one entry for
type: reference
? I kept getting an error that pointed to https://www.sanity.io/help/schema-array-of-invalid when I tried to make multiple
{type: 'reference', to: [a single type]}
. I tried uniquely `name`ing them on both the
to
values, and the reference type itself, but it's hung up on the fact I have dozens of
reference
types in the
type: 'array'
.
Currently reverted back to just a single
type: 'reference'
with a lot of
to
values, but it's problematic because of the many types I have, many of them have hundreds of results, making it very difficult for me to say I want "this document" from "this type"
The generated groq from that on dash is quite huge too since it has to match on a ton of fields on each type
😐
AI Update

You're actually using the correct, standard approach for references in Sanity! The pattern you described—a single reference type with multiple document types in the to array—is exactly what the official documentation recommends:

{
  title: 'Directors',
  name: 'directors',
  type: 'array',
  of: [
    {
      type: 'reference',
      to: [
        {type: 'person'},
        {type: 'company'},
        // ... all your other types
      ]
    }
  ]
}

The schema-array-of-invalid error you encountered likely happened if you tried creating multiple separate reference objects with different name properties in the array's of property. While technically possible, that's an unconventional pattern and not what the docs demonstrate.

For your usability problem (hundreds of documents making it hard to find what you want), here are some better solutions:

1. Use filter to constrain the reference picker

You can add filters to narrow down what appears in the reference picker based on document properties:

{
  type: 'array',
  name: 'items',
  of: [{
    type: 'reference',
    to: [
      {type: 'typeA'},
      {type: 'typeB'},
      // ... dozens more
    ],
    options: {
      filter: '_type == $selectedType',
      filterParams: {selectedType: 'typeA'} // Could be dynamic
    }
  }]
}

2. Add a custom filter UI

You can create a custom input component that lets editors first select which document type they want to reference, then shows only documents of that type.

3. Use disableNew if needed

If you don't want inline document creation cluttering the UI:

options: {
  disableNew: true
}

About the GROQ queries

Yes, a reference with many types in to will generate larger queries, but that's just how references work. The query needs to handle all possible types. You can optimize your frontend queries by only dereferencing the fields you actually need:

*[_type == "yourDoc"] {
  items[]-> {
    _type,
    // only the fields you need, not everything
    title,
    slug
  }
}

The error message you hit was likely because of a schema syntax issue (maybe duplicate names or incorrect nesting), not because Sanity limits the number of types in a reference. If you share the specific error or schema structure, I can help debug further!

Show original thread
12 replies
Do you have it set up like this?

fields: [
  ...,
  {
    name: "involved",
    title: "People Involved",
    type: 'array',
    of: [
      {
        type: "reference",
        to: [{ type: "managers" }, { type: "staff" }],
      },
    ],
  },
...
}

thats what i currently have it set up as, but I would like to have multiple
type: 'reference'
inside it so I can have more targeted search by types
Or some means of being able to select what type that was given to it in the reference link dialog. Right now the choice is search all the `to`s, which is like dumping the entire dataset every search
You can’t have multiple ones like you describe unfortunately, but would it help with a filter? https://www.sanity.io/docs/reference-type#filter-ebd7a95f9dc6
Right now the choice is search all the `to`s, which is like dumping the entire dataset every search
This shouldn't be a concern, it's basically the same as any query to the dataset, but I get why the user experience might not be the best if you don't what to search for.
The solution here is to add
name
 to the array fields so that the studio knows how to differ between them.
{
      name: 'multipleReferences',
      type: 'array',
      of: [
        {
          name: 'referenceA',
          type: 'reference',
          to: [{type: 'a'}],
          title: 'Make reference to A docs'
        },
        {
          name: 'referenceB',
          type: 'reference',
          to: [{type: 'b'}],
          title: 'Make reference to B docs'
        }
      ]
    },

This will change the array items` 
_type
 from
reference
 to
referenceA
and
referenceB
Wish it didn't change the _type (current auto-dereferencing code I wrote doesn't understand that) but I guess I can match on _type
^reference(_\w*)?
and pray everyone follows convention.
You can look for the
_ref
key?
That’s the best guarantee. I see your point though!
Probably, but is that _ref key protected like _type is (as in, I can't make a field
name: '__ref')
? (you're drunk slack, get some coffee)
Good to know though. A coworker recently fell into that
name
trap and neither of us could figure out what was going on (outside of "name seems to be dangerous, dont use it)". Now I can explain it lol
I don’t think it’s protected like that, but I have never observe anyone use it outside of the reference context. We should probably throw a warning if you do add field names that corresponds with those we use for specific things

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?