Nov 29, 2023
Dev Agrawal
Clerk's User and Organization Profiles can be extended with Custom Pages! Here's how.
Clerk provides a fully pre-built User Profile component that offers user a self-service portal for user functionality like managing emails, OAuth connections, signed in devices, etc. But if you want to provide additional user-specific functionality, instead of building a separate UI, you can build that interface directly into Clerk’s User Profile!
Let’s start with the out-of-the-box UserProfile
component.
User Profile Component1<UserProfile />
We can create a new page simply like this
New User Profile Page1<UserProfile> // Pass the page as children2<UserProfile.Page3label="New page"4url="new" // URL for the page within Clerk's internal routing5labelIcon={<FaStar />}6>7New Page8</UserProfile.Page>9</UserProfile>
We can use this page for things like subscription plans
User Profile page for Subscription plan1<UserProfile>2<UserProfile.Page label="Plan" url="plan" labelIcon={<FaStar />}>3<div>4<h3 className="text-3xl font-semibold">Plans</h3>5<p className=" text-gray-600">Manage your subscription plans</p>6<h4 className="mt-8 border-b py-1">Personal subscription</h4>7<p className="px-4 py-2">You are currently on the free plan.</p>8<button className="rounded border bg-blue-300 p-2 px-4 py-2">9Upgrade to Pro for $10/month10</button>11</div>12</UserProfile.Page>13</UserProfile>
We can access state and context in these components as expected
Custom pages can access state and context1<UserProfile>2<UserProfile.Page label="Plan" url="plan" labelIcon={<FaStar />}>3<PlanPage />4</UserProfile.Page>5</UserProfile>67...89const PlanPage = () => {10const { isPro } = useUser(); // example custom hook1112return (13<div>14<h3 className="text-3xl font-semibold">Plans</h3>15<p className=" text-gray-600">Manage your subscription plans</p>16<h4 className="mt-8 border-b py-1">Personal subscription</h4>17<p className="px-4 py-2">18You are currently on the {isPro ? `pro` : `free`} plan.19</p>20{isPro ? (21<button className="rounded border bg-gray-50 px-4 py-2">22Downgrade23</button>24) : (25<button className="rounded border bg-blue-300 p-2 px-4 py-2">26Upgrade to Pro for $10/month27</button>28)}29</div>30);31};
In Next.js App Router, <UserProfile>
and <UserProfile.Page>
has to be rendered in a client component. However, we can use a server component to render the page inside through render props (lifting content up).
Custom pages can be server components1// profile.tsx (client component)2"use client"34export const CustomUserProfile = (props: { PlanPage: React.ReactNode }) => {5return (6<UserProfile>7<UserProfile.Page label="Plan" url="plan" labelIcon={<FaStar />}>8{props.PlanPage}9</UserProfile.Page>10</UserProfile>11);12};1314// page.tsx (server component)15export default async function Page() {16const { isPro } = await getSubscription(); // data fetching on the server1718return (19<main>20<CustomUserProfile21PlanPage={22<div>23<h3 className="text-3xl font-semibold">Plans</h3>24<p className=" text-gray-600">Manage your subscription plans</p>25<h4 className="mt-8 border-b py-1">Personal subscription</h4>26<p className="px-4 py-2">27You are currently on the {isPro ? `pro` : `free`} plan.28</p>29{isPro ? (30<button className="rounded border bg-gray-50 px-4 py-2">31Downgrade32</button>33) : (34<button className="rounded border bg-blue-300 p-2 px-4 py-2">35Upgrade to Pro for $10/month36</button>37)}38</div>39}40/>41</main>42);43}
Custom Pages can also be added to the Organization Profile in the same way.
Custom pages in Organization Profile1<OrganizationProfile>2<OrganizationProfile.Page label="New page" url="new" labelIcon={<FaStar />}>3New Page4</OrganizationProfile.Page>5</OrganizationProfile>;
Custom pages allows you to extend the already powerful User and Organization Profile components with additional features specific to your use case. Combined with the appearance prop, this level of customization eliminates the effort spent into building entirely custom UIs for user and org management to support extra functionality.
Check out the full documentation on Custom Pages.
Clerk’s components work out of the box, handle every authentication and user management workflow, and are highly customizable and extendable. Learn more about Clerk’s Components, and get started with authentication in your Next.js app within minutes!
Start completely free for up to 10,000 monthly active users and up to 100 monthly active orgs. No credit card required.
Learn more about our transparent per-user costs to estimate how much your company could save by implementing Clerk.
The latest news and updates from Clerk, sent to your inbox.