Social Profile Page
Actor profile page with header, timeline, about panel, and followers grid.
1920px
OpenInstallation
npx shadcn@latest add https://ui.uptoolkit.com/r/social-profile-page.jsonUsage
An actor's profile: header with cover and stats, their timeline, mutual contacts, and a followers
grid. Every block reads the same ActivityPubActor, so there is one source of truth on the page.
npx shadcn@latest add @_cn/social-profile-pageInstalls to app/profile/page.tsx. Move it to a dynamic segment such as
app/[handle]/page.tsx and resolve the actor from the route:
import { buildWebFingerUrl, parseHandle } from "@/lib/activitypub";
export default async function Page({ params }: { params: Promise<{ handle: string }> }) {
const { handle } = await params;
const actor = await resolveActorByHandle(handle); // WebFinger, then fetch the actor document
const outbox = await fetchOutbox(actor);
// ...pass actor and outbox into ProfileHeader, SocialFeed, and ActorGrid
}parseHandle and buildWebFingerUrl from activitypub cover the
discovery half of that lookup.
Structured data
The page emits one Schema.org ProfilePage whose mainEntity is the actor and whose hasPart lists
the visible posts. The header's own JSON-LD is switched off with includeJsonLd={false}, and the
followers grid does the same, so the page produces a single profile node instead of three
overlapping ones.