Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

How to get the currently logged in user inside a Sanity schema

16 replies
Last updated: Dec 12, 2022
https://www.sanity.io/docs/migration-cheat-sheet#713ae1bbd4d3 This is still confusing me. I simply need the currently logged in user inside of a schema.

import {useClient, useCurrentUser} from 'sanity'

const GetUserRoles = () => {
    const user = useCurrentUser()
    const {roles} = user
    return roles
}
This doesn't work. Also,
this doesn't look right.
user
!==
currentUser
, must be a typo.Also, this gives an error... it wants export function
MyComponent () {
Is this a typescript shortcut or something?

export function MyComponent {
  const user = useCurrentUser()
  const {id, name, email, profileImage, provider, roles} = currentUser

  return <div>JSX</div>
}
Dec 12, 2022, 3:49 PM
That's usually available in the
context
passed to certain parts of the schema. What are your trying to do with the current user?
Dec 12, 2022, 7:31 PM
I'm trying to control how the array is built for an array field. It's a page builder, so only certain roles can add certain types of page components. I really don't need a Custom Input Component, so I'm trying to avoid that.
Dec 12, 2022, 7:52 PM
Can you share how you currently have this implemented in a V2 studio (if you have it) or what you have so far?
Dec 12, 2022, 7:58 PM
It wasn't possible in the V2 studio without creating a custom input component, actually, but I can show you some of the V3 code:
Dec 12, 2022, 8:02 PM
//array
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"},
            ....
    ]

//schema field

{
    group: "content",
        name: "contentBlocks",
    title: "Content Blocks",
    type: "array",
    of: pageBlocks
},
   

Dec 12, 2022, 8:02 PM
Got it. The current user isn't provided to your schema like this and you can't use asynchronous code when defining your schema, so you wouldn't be able to fetch the current user. I'm afraid you'll have to use a custom input component, fetch the current user, filter your
pageBlocks
array based off of their role, then use the
renderDefault
option to display the default input component for that list. I can help you put it together if you need!
Dec 12, 2022, 8:06 PM
There are examples in the v3 migration guide for Custom Input Componens using string and object, but not array. Is there an example somewhere?
Dec 12, 2022, 8:09 PM
I don't think there is actually. I can try to put one together this afternoon, though.
Dec 12, 2022, 8:13 PM
Try, I can also try to work through one.
Dec 12, 2022, 8:13 PM
But I wonder: will it look exactly the same as the default type?
Dec 12, 2022, 8:13 PM
This has been a feature I've been wanting since forever, so I'm trying to make it happen.
Dec 12, 2022, 8:14 PM
Yeah, the renderDefault function just renders the original input so it should look the same as the default type.
Dec 12, 2022, 8:15 PM
Ok, thanks.
Dec 12, 2022, 8:15 PM
Ok, here's an example:
{
      name: 'contentBlocks',
      title: 'Content Blocks',
      type: 'array',
      of: pageBlocks,
      components: {
        input: RolesBasedArrayInput,
      },
    },

import React from 'react'
import {useCurrentUser} from 'sanity'

export function RolesBasedArrayInput(props) {
  const {schemaType, renderDefault} = props
  const {role} = useCurrentUser()

  const allowedTypes =
    role == 'administrator'
      ? schemaType.of
      : schemaType.of.filter((type) => !['aDayInTheLifeBlock', 'careerBlock'].includes(type.name))

  return <>{renderDefault({...props, schemaType: {...schemaType, of: allowedTypes}})}</>
}
Dec 12, 2022, 9:22 PM
Oh wow, thanks!
Dec 12, 2022, 9:23 PM
You're welcome!
Dec 12, 2022, 9:23 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?