Files
spsays-training/app/(app)/u/[handle]/profile-og.ts
2026-06-02 01:57:08 +05:30

48 lines
1.5 KiB
TypeScript

/**
* Shared `generateMetadata` helper for /u/[handle] routes.
*
* Both `/u/[handle]/page.tsx` (Posts tab) and `/u/[handle]/posts/page.tsx`
* (scroll feed) want the same profile-flavoured OG card on direct URL
* shares — the difference between the two is purely the rendered body,
* not the social preview. This helper fetches the profile via the
* server-side BFF client and hands it to the canonical `ogForProfile`
* builder.
*
* Failures (404 handle, BFF unreachable, malformed payload) fall back
* to the site-level `ogDefault` so unfurlers still get a valid card
* rather than nothing.
*
* Note: the page's underlying `app/u/[handle]/layout.tsx` is a client
* component and can't export `generateMetadata`. The metadata has to
* live on the (server) page that mounts the client tree, which is why
* we slim each page.tsx down to a server shell + a separate client
* content file.
*/
import type { Metadata } from "next";
import { bff } from "@/lib/bff";
import { ogDefault, ogForProfile } from "@/lib/og";
type PublicProfileForOg = {
handle: string;
name: string;
post_count?: number;
};
export async function metadataForHandle(handle: string): Promise<Metadata> {
try {
const profile = await bff<PublicProfileForOg>(
`/u/${encodeURIComponent(handle)}`,
{ revalidate: 60 },
);
if (!profile) return ogDefault();
return ogForProfile({
handle: profile.handle,
name: profile.name,
postCount: profile.post_count,
});
} catch {
return ogDefault();
}
}