Setting field schema settings based on user roles in Sanity.io

3 replies
Last updated: Aug 15, 2024
Hey all,
Would anyone know if it's possible to set up individual field schema settings based on the user's role, for example set a field to hidden or readonly if it's specific role viewing the document? I know there is a useCurrentUser hook, but that can only be used in a React component, not in schema or config files, and I don't have custom components, I'm using the basic field types (e.g. string, image etc). What would be a good solution for this?
AI Update

Great question! Yes, you can absolutely set up field-level permissions based on user roles using conditional fields in your schema. The good news is that you don't need custom components to do this.

The hidden and readOnly properties in your schema can accept callback functions, and these callbacks receive a currentUser parameter that you can use to check roles. Here's how you can implement this:

{
  name: 'sensitiveField',
  type: 'string',
  hidden: ({currentUser}) => {
    // Hide this field for users with 'viewer' role
    return currentUser?.roles?.some(role => role.name === 'viewer')
  }
}

Or to make a field read-only for certain roles:

{
  name: 'importantField',
  type: 'string',
  readOnly: ({currentUser}) => {
    // Make read-only for everyone except admins
    return !currentUser?.roles?.some(role => role.name === 'administrator')
  }
}

The callback function receives an object with several useful properties including currentUser, document, parent, and value. The currentUser object contains information about the currently logged-in user, including their roles.

Example with Multiple Conditions

You can combine user role checks with document state conditions:

{
  name: 'approvalField',
  type: 'string',
  readOnly: ({currentUser, document}) => {
    // Only editors can modify this field, and only when document is in draft state
    const isEditor = currentUser?.roles?.some(role => role.name === 'editor')
    const isDraft = document?.status === 'draft'
    return !isEditor || !isDraft
  }
}

Important Considerations

  1. Validation: If a field is marked as required, it will still enforce validation even when hidden. You may need to implement conditional validation to handle this properly.

  2. Security: Remember that hiding/making fields read-only in the Studio is a UX feature, not a security feature. You should still implement proper access control rules in your project's access control configuration to truly restrict what users can modify via the API.

This approach works with all basic field types (string, image, number, etc.) without needing custom components, making it a clean solution for role-based field visibility. The conditional fields feature was introduced specifically to handle these kinds of dynamic form behaviors based on document state and user context.

The
currentUser
is passed into that
context
in the second argument of hidden/read only callbacks. You can find out a user’s role there!
That works, thanks!
You’re welcome!

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?