👋 Next.js Conf 2024: Come build, party, run, and connect with us! See all events

How to allow only an array of projects chosen from the Work page in Sanity.io

5 replies
Last updated: Apr 22, 2024
Hi all! I’m having a little trouble, seeing if anyone has some insight here…
I have a work page that will have an array of projects to choose from and sort like so:

export default defineType({
  name: 'work',
  title: 'Work',
  type: 'document',
  singleton: true,
  fields: [
    // ...
    defineField({
      name: 'projects',
      title: 'Projects',
      type: 'array',
      of: [
        {
          type: 'reference',
          to: {
            type: 'project'
          }
        }
      ]
    })
  ]
});
Now, on my home / index page, I’d like to have an array of “featured” projects - but instead of choosing from the general list of “all projects” like on the Work schema above with the
to: { type: 'project' }
, can I somehow allow only an array of projects chosen from the Work page?
Home page looks like this:

export default defineType({
  name: 'index',
  title: 'Home',
  type: 'document',
  singleton: true,
  fields: [
    // ...
    defineField({
      name: 'featuredProjects',
      title: 'Featured Projects',
      type: 'array',
      of: [
        {
          type: 'reference',
          to: {
            type: 'project' // change this to point to the array of work projects from the schema above?
          }
        }
      ]
    })
  ]
});

Let’s say the client has published 10 projects. On the work page they have added 6 projects. Then on the home page, they should only be able to choose from the 6 projects in the work page, and not all 10 projects…
Let me know if this makes sense or if I should elaborate more, ha.

Thanks!!
Apr 19, 2024, 10:27 PM
Yes, you can do this with a
filter
on your reference field. Something like:
{
      name: 'featuredProjects',
      type: 'reference',
      to: [{ type: 'project' }],
      options: {
        filter: async ({ getClient }) => {
          const client = getClient({ apiVersion: '2024-04-19' });

          const referencedProjectIds = await client.fetch(
            `*[_type == 'project' && count(*[_type == 'work' && references(^._id)]) > 0]._id`
          );

          return {
            filter: '_id in $referencedProjectIds',
            params: { referencedProjectIds },
          };
        },
      },
    },
  
Apr 19, 2024, 11:01 PM
Hi
user M
, thanks for the quick reply and great example! I just tried this out, it is kind of working…• I can choose from the projects on the Work page (nice!), but I can only select one project. There is no option to add more, do I need to change
type: 'reference'
to
'array'
?• One other small quirk - when this featuredProjects field is empty, there is a “+ Create” button - any way t hide this? Not trying to create a new project from here…
Thanks again!
Apr 19, 2024, 11:23 PM
Update! 😎 I got this working with the following:
{
  name: 'featuredProjects',
  title: 'Featured Projects',
  type: 'array',
  of: [
    {
      type: 'reference',
      to: [{ type: 'project' }],
      options: {
        ... // same as code above
      }
    }
  ]
}
I think the “+ Create” button is a different topic entirely, I’ll keep Googlin’ this, if you have any ideas or links you could point me towards, that’d be awesome!

Thanks again, problem solved!
Apr 19, 2024, 11:35 PM
Annnnd another victory! In my sanity.config file, I added this document object that hides the Create button on my list of projects on the home page.

export default defineConfig({
  ...
  document: {
    newDocumentOptions: (prev, { currentUser, creationContext }) => {
      if (creationContext.type === 'document' && creationContext.schemaType === 'index') {
        return [];
      }
      return prev;
    }
  }
}
No more questions, all problems solved.
👍
Apr 20, 2024, 12:10 AM
Awesome! Glad you got it sorted!
Apr 22, 2024, 3:45 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?