👀 See Sanity in action: Watch product demo now →

Filter Array Options Based on the Current User Role

By RD Pennell

Use the renderDefault function to easily control your available array options.

pageBuilder.js

import {RolesBasedArrayInput} from './RolesBasedArrayInput'

const pageBlocks = [
  {type: 'aDayInTheLifeBlock', title: 'A Day In The Life'},
  {type: 'beyondTheClassroomBlock', title: 'Beyond The Classroom'},
  {type: 'careerBlock', title: 'Career Block'},
  {type: 'cta', to: [{type: 'cta'}], title: 'Call to Action'},
]

export default {
  name: 'pageBuilder',
  title: 'Page Builder',
  type: 'document',
  fields: [
    // other fields
    {
      name: 'contentBlocks',
      title: 'Content Blocks',
      type: 'array',
      of: pageBlocks,
      components: {
        input: RolesBasedArrayInput,
      },
    },
  ],
}

RolesBasedArrayInput.js

import {useCurrentUser} from 'sanity'

export function RolesBasedArrayInput(props) {
  const {schemaType, renderDefault} = props
  
  //get the role of the current user
  const {role} = useCurrentUser() 
  
  //if the user is an admin, return all types. If not, filter some of them out. 
  const allowedTypes =
    role == 'administrator'
      ? schemaType.of
      : schemaType.of.filter((type) => !['aDayInTheLifeBlock', 'careerBlock'].includes(type.name))
      
  //render the default component and replace the allowed types
  return renderDefault({...props, schemaType: {...schemaType, of: allowedTypes}})
}

Often, you'll want to allow array options for some roles but not for others. Since you can't have conditional array options in your schema, you'll need to use a custom component to perform the logic instead. Luckily with the V3 custom component API we can leverage the renderDefault method (passed in through props) to render the default component. This means we can do this without writing any JSX!

In this example, we have a page builder document with an array of content block options, but we only want our project administrators to add Career or Day in the Life blocks. This can be adjusted for any role or content type you need, though!

Contributor

Other schemas by author