<UserProfile /> customization
The <UserProfile /> component supports the addition of custom pages and use of external links in the navigation sidebar.
<UserProfile.Page />
Custom pages can be rendered inside the <UserProfile /> component and provide a way to incorporate app-specific settings or additional functionality.
To add a custom page to the <UserProfile /> component, use the <UserProfile.Page /> component.
Usage
<UserProfile.Page /> can be rendered only on the client. For Next.js applications using App Router, the "use client"; directive must be added.
/app/user-profile/[[...user-profile]]/page.tsx"use client"; import { UserProfile } from "@clerk/nextjs"; import { CustomProfilePage, CustomTerms } from "../components"; import { CustomIcon } from "../icons"; const UserProfilePage = () => ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Page label="Custom Page" labelIcon={<CustomIcon />} url="custom-page"> <CustomProfilePage /> </UserProfile.Page> <UserProfile.Page label="Terms" labelIcon={<CustomIcon />} url="terms"> <CustomTerms /> </UserProfile.Page> </UserProfile> ); export default UserProfilePage;
/pages/user-profile/[[...index]].tsximport { UserProfile } from "@clerk/nextjs"; import { CustomProfilePage, CustomTerms } from "../components"; import { CustomIcon } from "../icons"; const UserProfilePage = () => ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Page label="Custom Page" labelIcon={<CustomIcon />} url="custom-page"> <CustomProfilePage /> </UserProfile.Page> <UserProfile.Page label="Terms" labelIcon={<CustomIcon />} url="terms"> <CustomTerms /> </UserProfile.Page> </UserProfile> ); export default UserProfilePage;
/user-profile.tsximport { UserProfile } from "@clerk/clerk-react"; import { CustomProfilePage, CustomTerms } from "../components"; import { CustomIcon } from "../icons"; const UserProfilePage = () => ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Page label="Custom Page" labelIcon={<CustomIcon />} url="custom-page"> <CustomProfilePage /> </UserProfile.Page> <UserProfile.Page label="Terms" labelIcon={<CustomIcon />} url="terms"> <CustomTerms /> </UserProfile.Page> </UserProfile> ); export default UserProfilePage;
routes/user/$.tsximport { UserProfile } from "@clerk/remix"; import { CustomProfilePage, CustomTerms } from "../components"; import { CustomIcon } from "../icons"; export default function UserProfilePage() { return ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Page label="Custom Page" labelIcon={<CustomIcon />} url="custom-page"> <CustomProfilePage /> </UserProfile.Page> <UserProfile.Page label="Terms" labelIcon={<CustomIcon />} url="terms"> <CustomTerms /> </UserProfile.Page> </UserProfile> ); }
Props
All props below are required.
| Name | Type | Description |
|---|---|---|
label | string | The name that will be displayed in the navigation sidebar for the custom page. |
labelIcon | React.ReactElement | An icon displayed next to the label in the navigation sidebar. |
url | string | The path segment that will be used to navigate to the custom page. (e.g. if the UserProfile component is rendered at /user, then the custom page will be accessed at /user/{url} when using path routing) |
children | React.ReactElement | The components to be rendered as content inside the custom page. |
<UserProfile.Link />
You can add external links to the <UserProfile /> navigation sidebar using the <UserProfile.Link /> component.
Usage
<UserProfile.Link /> can be rendered only on the client. For Next.js applications using App Router, the "use client"; directive must be added.
/app/user-profile/[[...user-profile]]/page.tsx"use client"; import { UserProfile } from "@clerk/nextjs"; import { CustomIcon } from "../icons"; const UserProfilePage = () => ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Link label="Homepage" labelIcon={<CustomIcon />} url="/home" /> </UserProfile> ); export default UserProfilePage;
/pages/user-profile/[[...index]].tsximport { UserProfile } from "@clerk/nextjs"; import { CustomIcon } from "../icons"; const UserProfilePage = () => ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Link label="Homepage" labelIcon={<CustomIcon />} url="/home" /> </UserProfile> ); export default UserProfilePage;
/user-profile.tsximport { UserProfile } from "@clerk/clerk-react"; import { CustomIcon } from "../icons"; const UserProfilePage = () => ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Link label="Homepage" labelIcon={<CustomIcon />} url="/home" /> </UserProfile> ); export default UserProfilePage;
routes/user/$.tsximport { UserProfile } from "@clerk/remix"; import { CustomIcon } from "../icons"; export default function UserProfilePage() { return ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Link label="Homepage" labelIcon={<CustomIcon />} url="/home" /> </UserProfile> ); }
Props
All props below are required.
| Name | Type | Description |
|---|---|---|
label | string | The name that will be displayed in the navigation sidebar for the link. |
labelIcon | React.ReactElement | An icon displayed next to the label in the navigation sidebar. |
url | string | The absolute or relative url to navigate to |
Advanced use cases
Reordering default routes
If you want to reorder the default routes (Account and Security) in the UserProfile navigation sidebar, you can use the <UserProfile.Page /> component with the label prop set to 'account' or 'security'. This will target the existing default page and allow you to rearrange it.
Usage
<UserProfile.Page /> and <UserProfile.Link /> can be rendered only on the client. For Next.js applications using App Router, the "use client"; directive must be added.
/app/user-profile/[[...user-profile]]/page.tsx"use client"; import { UserProfile } from "@clerk/nextjs"; import { MyCustomPageContent } from "../components"; import { CustomIcon, Icon } from "../icons"; const UserProfilePage = () => ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Page label="Custom Page" url="custom" labelIcon={<CustomIcon />}> <MyCustomPageContent /> </UserProfile.Page> <UserProfile.Link label="Homepage" url="/home" labelIcon={<Icon />} /> <UserProfile.Page label="account" /> <UserProfile.Page label="security" /> </UserProfile> ); export default UserProfilePage;
/pages/user-profile/[[...index]].tsximport { UserProfile } from "@clerk/nextjs"; import { MyCustomPageContent } from "../components"; import { CustomIcon, Icon } from "../icons"; const UserProfilePage = () => ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Page label="Custom Page" url="custom" labelIcon={<CustomIcon />}> <MyCustomPageContent /> </UserProfile.Page> <UserProfile.Link label="Homepage" url="/home" labelIcon={<Icon />} /> <UserProfile.Page label="account" /> <UserProfile.Page label="security" /> </UserProfile> ); export default UserProfilePage;
/user-profile.tsximport { UserProfile } from "@clerk/clerk-react"; import { MyCustomPageContent } from "../components"; import { CustomIcon, Icon } from "../icons"; const UserProfilePage = () => ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Page label="Custom Page" url="custom" labelIcon={<CustomIcon />}> <MyCustomPageContent /> </UserProfile.Page> <UserProfile.Link label="Homepage" url="/home" labelIcon={<Icon />} /> <UserProfile.Page label="account" /> <UserProfile.Page label="security" /> </UserProfile> ); export default UserProfilePage;
routes/user/$.tsximport { UserProfile } from "@clerk/remix"; import { MyCustomPageContent } from "../components"; import { CustomIcon, Icon } from "../icons"; export default function UserProfilePage() { return ( <UserProfile path="/user-profile" routing="path"> <UserProfile.Page label="Custom Page" url="custom" labelIcon={<CustomIcon />}> <MyCustomPageContent /> </UserProfile.Page> <UserProfile.Link label="Homepage" url="/home" labelIcon={<Icon />} /> <UserProfile.Page label="account" /> <UserProfile.Page label="security" /> </UserProfile> ); }
The above example will result in the following order:
- Custom Page
- Homepage
- Account
- Security
It's important to note that the first page in the list will be rendered under the root path / (its url will be ignored) and the Clerk pages will be rendered under the path /account. Also, the first item in the list cannot be a <UserProfile.Link /> component.
Using custom pages with the <UserButton /> component
If you are using the <UserButton /> component with the default props (where the UserProfile opens as a modal), then you should also be providing these custom pages as children to the component (using the <UserButton.UserProfilePage /> and <UserButton.UserProfileLink /> components respectively).
Usage
<UserButton.UserProfilePage /> and <UserButton.UserProfileLink /> can be rendered only on the client. For Next.js applications using App Router, the "use client"; directive must be added.
/app/components/Header.tsx"use client"; import { UserButton } from "@clerk/nextjs"; import { MyCustomPageContent } from "../components"; import { CustomIcon, Icon } from "../icons"; const Header = () => ( <header> <UserButton afterSignOutUrl='/'> <UserButton.UserProfilePage label="Custom Page" url="custom" labelIcon={<CustomIcon />}> <MyCustomPageContent /> </UserButton.UserProfilePage> <UserButton.UserProfileLink label="Homepage" url="/home" labelIcon={<Icon />} /> <UserButton.UserProfilePage label="account" /> <UserButton.UserProfilePage label="security" /> </UserButton> </header> ); export default Header;
/pages/components/Header.tsximport { UserButton } from "@clerk/nextjs"; import { MyCustomPageContent } from "../components"; import { CustomIcon, Icon } from "../icons"; const Header = () => ( <header> <UserButton afterSignOutUrl='/'> <UserButton.UserProfilePage label="Custom Page" url="custom" labelIcon={<CustomIcon />}> <MyCustomPageContent /> </UserButton.UserProfilePage> <UserButton.UserProfileLink label="Homepage" url="/home" labelIcon={<Icon />} /> <UserButton.UserProfilePage label="account" /> <UserButton.UserProfilePage label="security" /> </UserButton> </header> ); export default Header;
/components/Header.tsximport { UserButton } from "@clerk/clerk-react"; import { MyCustomPageContent } from "../components"; import { CustomIcon, Icon } from "../icons"; const Header = () => ( <header> <UserButton afterSignOutUrl='/'> <UserButton.UserProfilePage label="Custom Page" url="custom" labelIcon={<CustomIcon />}> <MyCustomPageContent /> </UserButton.UserProfilePage> <UserButton.UserProfileLink label="Homepage" url="/home" labelIcon={<Icon />} /> <UserButton.UserProfilePage label="account" /> <UserButton.UserProfilePage label="security" /> </UserButton> </header> ); export default Header;
components/Header.tsximport { UserButton } from "@clerk/remix"; import { MyCustomPageContent } from "../components"; import { CustomIcon, Icon } from "../icons"; export default function Header() { return ( <header> <UserButton afterSignOutUrl='/'> <UserButton.UserProfilePage label="Custom Page" url="custom" labelIcon={<CustomIcon />}> <MyCustomPageContent /> </UserButton.UserProfilePage> <UserButton.UserProfileLink label="Homepage" url="/home" labelIcon={<Icon />} /> <UserButton.UserProfilePage label="account" /> <UserButton.UserProfilePage label="security" /> </UserButton> </header> ); }
This repetition of the same property can be avoided when the user is using the userProfileMode='navigation' and userProfileUrl='<some url>' props on the <UserButton /> component and has implemented a dedicated page for the <UserProfile /> component.