Add custom items and links to the <UserButton />
component
The <UserButton />
component supports custom menu items, allowing the incorporation of app-specific settings or additional functionality.
To add a custom menu item to the <UserButton />
component, use the <UserButton.MenuItems />
component.
There are two types of custom menu items available:
<UserButton.Action>
- A menu item that triggers an action when clicked.
<UserButton.Link>
- A menu item that navigates to a page when clicked.
Custom actions can be rendered inside the <UserButton />
component using the <UserButton.Action />
component. This component is useful for adding actions like opening a chat or triggering a modal.
The <UserButton />
component must be wrapped in a <UserButton.MenuItems />
component to render the custom action.
<UserButton.Action />
accepts the following props:
Name label
Type string
Description The name that will be displayed in the menu of the user button.
Name labelIcon
Type React.ReactElement
Description An icon displayed next to the label in the menu.
Name open?
Type string
Description The path segment that will be used to open the user profile modal to a specific page.
Name onClick?
Type void
Description A function to be called when the menu item is clicked.
The following example demonstrates how to add an action to the <UserButton />
component.
/app /page.tsx 'use client'
import { UserButton } from '@clerk/nextjs'
const DotIcon = () => {
return (
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 512 512" fill = "currentColor" >
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" />
</ svg >
)
}
export default function Home () {
return (
< header >
< UserButton >
< UserButton.MenuItems >
< UserButton.Action
label = "Open chat"
labelIcon = {< DotIcon />}
onClick = {() => alert ( 'init chat' )}
/>
</ UserButton.MenuItems >
</ UserButton >
</ header >
)
}
In Astro components, props are converted to strings, so you can't use an onClick
handler to handle click events. Instead, you can set an arbitrary prop, set up a custom event listener that will check for the value passed to that prop, and then execute a desired action based on that value.
For example, clickIdentifier
is the arbitrary prop being used to identify the click event. Two <UserButton.Action />
components are added to the menu, each with a different clickIdentifier
prop. When the menu item is clicked, the custom event listener will check for the value passed to the clickIdentifier
prop, either "open_chat"
or "open_cart"
, and then execute an action based on that value.
pages /index.astro ---
import { UserButton } from '@clerk/astro/components'
---
< header >
< UserButton >
< UserButton . MenuItems >
< UserButton . Action label = "Open chat" clickIdentifier = "open_chat" >
< svg
slot = "label-icon"
xmlns = "http://www.w3.org/2000/svg"
viewBox = "0 0 512 512"
fill = "currentColor"
>
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" ></ path >
</ svg >
</ UserButton . Action >
< UserButton . Action label = "Open cart" clickIdentifier = "open_cart" >
< svg
slot = "label-icon"
xmlns = "http://www.w3.org/2000/svg"
viewBox = "0 0 512 512"
fill = "currentColor"
>
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" ></ path >
</ svg >
</ UserButton . Action >
</ UserButton . MenuItems >
</ UserButton >
</ header >
< script >
document .addEventListener ( 'clerk:menu-item-click' , (e) => {
if ( e .detail === 'open_chat' ) {
console .log ( 'init chat' )
}
if ( e .detail === 'open_cart' ) {
console .log ( 'init cart' )
}
})
</ script >
The following example demonstrates how to add an action, as well as a custom page , to the <UserButton />
component.
/app /page.tsx 'use client'
import { UserButton } from '@clerk/nextjs'
const DotIcon = () => {
return (
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 512 512" fill = "currentColor" >
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" />
</ svg >
)
}
export default function Home () {
return (
< header >
< UserButton >
< UserButton.MenuItems >
< UserButton.Action label = "Help" labelIcon = {< DotIcon />} open = "help" />
</ UserButton.MenuItems >
< UserButton.UserProfilePage label = "Help" labelIcon = {< DotIcon />} url = "help" >
< div >
< h1 >Help Page</ h1 >
< p >This is the custom help page</ p >
</ div >
</ UserButton.UserProfilePage >
</ UserButton >
</ header >
)
}
In the following example, the <UserButton.Action />
component is used to add a "Help" menu item to the <UserButton />
component. The open
prop is set to "help"
to open the /help
page when the menu item is selected.
The <UserButton.UserProfilePage />
component is used to render the /help
page, and because its configured as a user profile page, the <UserProfile />
modal will be opened with the custom "Help" menu item. Read more about custom pages.
pages /index.astro ---
import { UserButton } from '@clerk/astro/components'
---
< header >
< UserButton >
< UserButton . MenuItems >
< UserButton . Action label = "Help" open = "help" >
< svg
slot = "label-icon"
xmlns = "http://www.w3.org/2000/svg"
viewBox = "0 0 512 512"
fill = "currentColor"
>
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" ></ path >
</ svg >
</ UserButton . Action >
</ UserButton . MenuItems >
< UserButton . UserProfilePage label = "Help" url = "help" >
< svg
slot = "label-icon"
xmlns = "http://www.w3.org/2000/svg"
viewBox = "0 0 512 512"
fill = "currentColor"
>
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" ></ path >
</ svg >
< div >
< h1 >Help Page</ h1 >
< p >This is the custom help page</ p >
</ div >
</ UserButton . UserProfilePage >
</ UserButton >
</ header >
Custom links can be rendered inside the <UserButton />
component using the <UserButton.Link />
component. This component is useful for adding links to custom pages or external URLs.
The <UserButton />
component must be wrapped in a <UserButton.MenuItems />
component to render the custom link.
<UserButton.Link />
accept the following props, all of which are required :
Name label
Type string
Description The name that will be displayed in the menu of the user button.
Name labelIcon
Type React.ReactElement
Description An icon displayed next to the label in the menu.
Name href
Type string
Description The path segment that will be used to navigate to the custom page.
The following example demonstrates how to add a link to the <UserButton />
component.
/app /page.tsx 'use client'
import { UserButton } from '@clerk/nextjs'
const DotIcon = () => {
return (
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 512 512" fill = "currentColor" >
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" />
</ svg >
)
}
export default function Home () {
return (
< header >
< UserButton >
< UserButton.MenuItems >
< UserButton.Link
label = "Create organization"
labelIcon = {< DotIcon />}
href = "/create-organization"
/>
</ UserButton.MenuItems >
</ UserButton >
</ header >
)
}
pages /index.astro ---
import { UserButton } from '@clerk/astro/components'
---
< header >
< UserButton >
< UserButton . MenuItems >
< UserButton . Link label = "Create organization" href = "/create-organization" >
< svg
slot = "label-icon"
xmlns = "http://www.w3.org/2000/svg"
viewBox = "0 0 512 512"
fill = "currentColor"
>
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" ></ path >
</ svg >
</ UserButton . Link >
</ UserButton . MenuItems >
</ UserButton >
</ header >
The <UserButton />
component includes two default menu items: Manage account
and Sign out
. You can reorder these default items by setting the label
prop to 'manageAccount'
or 'signOut'
. This will target the existing default item and allow you to rearrange it, as shown in the following example:
/app /page.tsx 'use client'
import { UserButton } from '@clerk/nextjs'
const DotIcon = () => {
return (
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 512 512" fill = "currentColor" >
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" />
</ svg >
)
}
export default function Home () {
return (
< header >
< UserButton >
< UserButton.MenuItems >
< UserButton.Action label = "signOut" />
< UserButton.Link
label = "Create organization"
labelIcon = {< DotIcon />}
href = "/create-organization"
/>
< UserButton.Action label = "manageAccount" />
</ UserButton.MenuItems >
</ UserButton >
</ header >
)
}
pages /index.astro ---
import { UserButton } from '@clerk/astro/components'
---
< header >
< UserButton >
< UserButton . MenuItems >
< UserButton . Action label = "signOut" />
< UserButton . Link label = "Create organization" open = "/create-organization" >
< svg
slot = "label-icon"
xmlns = "http://www.w3.org/2000/svg"
viewBox = "0 0 512 512"
fill = "currentColor"
>
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" ></ path >
</ svg >
</ UserButton . Link >
< UserButton . Action label = "manageAccount" />
</ UserButton . MenuItems >
</ UserButton >
</ header >
With the above example, the <UserButton />
menu items will be in the following order:
Sign out
Create organization
Manage account
To conditionally render menu items based on a user's role or permissions, you can use the has()
helper function:
/app /page.tsx 'use client'
import { UserButton , useAuth } from '@clerk/nextjs'
const DotIcon = () => {
return (
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 512 512" fill = "currentColor" >
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" />
</ svg >
)
}
export default function Home () {
const { has , isLoaded } = useAuth ()
if ( ! isLoaded) {
return < span >Loading...</ span >
}
const isAdmin = has ({ permission : 'org:app:admin' })
return (
< header >
< UserButton >
{isAdmin && (
< UserButton.MenuItems >
< UserButton.Link
label = "Create organization"
labelIcon = {< DotIcon />}
href = "/create-organization"
/>
</ UserButton.MenuItems >
)}
</ UserButton >
</ header >
)
}
pages /index.astro ---
import { UserButton } from '@clerk/astro/components'
const { has } = Astro . locals .auth ()
const isAdmin = has ({ permission : 'org:app:admin' })
---
< header >
< UserButton >
{
isAdmin && (
< UserButton.MenuItems >
< UserButton.Link label = "Create organization" open = "/create-organization" >
< svg
slot = "label-icon"
xmlns = "http://www.w3.org/2000/svg"
viewBox = "0 0 512 512"
fill = "currentColor"
>
< path d = "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" />
</ svg >
</ UserButton.Link >
</ UserButton.MenuItems >
)
}
</ UserButton >
</ header >
With the above example, the "Create organization" menu item will only render if the current user has the org:app:admin
permission.