Wall Page
Profile wall page with a wall composer, filterable activity feed, and intro, photos, and friends rails.
1920px
OpenInstallation
npx shadcn@latest add https://ui.uptoolkit.com/r/wall-page.jsonUsage
Someone's wall: the header, a composer for visitors, and the full activity stream — their posts, other people's wall posts, reactions, follows, albums, and profile changes — with an intro, photos, and friends rail alongside.
npx shadcn@latest add @_cn/wall-pageInstalls to app/wall/page.tsx along with wall-feed and every block,
component, and helper it uses.
Wiring it to a real actor
Move the page to a dynamic segment and resolve the owner from the route:
import { buildWebFingerUrl, parseHandle } from "@/lib/activitypub";
export default async function Page({ params }: { params: Promise<{ handle: string }> }) {
const { handle } = await params;
const owner = await resolveActorByHandle(handle); // WebFinger, then fetch the actor document
const [outbox, friends] = await Promise.all([fetchOutbox(owner), fetchFollowers(owner)]);
// ...pass owner, outbox, and friends into ProfileHeader, WallFeed, and ActorGrid
}parseHandle and buildWebFingerUrl from activitypub cover the
discovery half of that lookup. Once the data is real, drop the now={SAMPLE_NOW} prop so timestamps
come from the clock.
The photos rail
The rail does not take its own list. It derives the thumbnails from the attachments already present in the wall collection, so the rail and the stream can never disagree about what has been posted.
Structured data
The page emits one Schema.org ProfilePage whose mainEntity is the owner and whose hasPart
lists the visible posts. The header's own JSON-LD is switched off with includeJsonLd={false}, and
the friends grid does the same, so the page produces a single profile node rather than three
overlapping ones. The feed still emits its own CollectionPage.
Related
social-profile-page is the timeline-only version of this page: same
actor, same header, but a plain post feed instead of the full activity vocabulary.