From c3e76d9963065d1403f42a509d40d9f1d7055d57 Mon Sep 17 00:00:00 2001 From: NiallJoeMaher Date: Sun, 14 Jun 2026 16:09:37 +0100 Subject: [PATCH] feat: branded dynamic OG/social cards via @vercel/og Replace the single Lato/planet OG card with the relaunch design system: five Satori-safe templates (main, post, profile, publication, job) served from one `/og` route, wired into every shareable page from real DB models. - lib/og/{tokens,fonts,templates}.ts(x): design tokens, Google-font loader (edge), and the card components. app/og/route.tsx dispatches on `type` and embeds the white wordmark (public/og/wordmark-white.png) as a cached data URI so Satori never resolves a same-origin mid-render. - lib/og/url.ts: typed builders (one per card) that map our models to the route's params, cap tags, and append a `v=` cache-buster. - utils/hue.ts: extract the deterministic per-string hue (was inline in the source-profile client) so OG avatars/marks match on-site tints. - Add openGraph.images + twitter (summary_large_image) to home/fallback, about, advertise, discussions, jobs, tag, speakers, volunteer, and the dynamic article/discussion/link/profile/publication/job pages. JSON-LD article image uses the same builder. - Long immutable cache-control on the route; runtime stays edge. Verified: all card types render 1200x630 PNGs and og:image resolves on real pages. Co-Authored-By: Claude Opus 4.8 (1M context) --- app/(app)/[username]/[slug]/page.tsx | 74 +++- app/(app)/[username]/page.tsx | 32 +- app/(app)/d/[slug]/page.tsx | 18 +- app/(app)/discussions/page.tsx | 18 +- app/(app)/jobs/[slug]/page.tsx | 68 +++- app/(app)/jobs/page.tsx | 19 +- app/(app)/s/[sourceSlug]/[slug]/page.tsx | 30 +- .../s/[sourceSlug]/_sourceProfileClient.tsx | 11 +- app/(app)/s/[sourceSlug]/page.tsx | 24 +- app/(app)/speakers/page.tsx | 5 + app/(app)/tag/[slug]/page.tsx | 10 + app/(app)/volunteer/page.tsx | 5 + app/(marketing)/about/page.tsx | 12 +- app/(marketing)/advertise/page.tsx | 22 +- app/layout.tsx | 10 +- app/og/route.tsx | 302 ++++++---------- lib/og/fonts.ts | 48 +++ lib/og/templates.tsx | 342 ++++++++++++++++++ lib/og/tokens.ts | 43 +++ lib/og/url.ts | 137 +++++++ lib/structured-data/schemas/article.ts | 11 +- public/og/wordmark-white.png | Bin 0 -> 77176 bytes utils/hue.ts | 10 + 23 files changed, 986 insertions(+), 265 deletions(-) create mode 100644 lib/og/fonts.ts create mode 100644 lib/og/templates.tsx create mode 100644 lib/og/tokens.ts create mode 100644 lib/og/url.ts create mode 100644 public/og/wordmark-white.png create mode 100644 utils/hue.ts diff --git a/app/(app)/[username]/[slug]/page.tsx b/app/(app)/[username]/[slug]/page.tsx index f7122466b..b6e6f8e82 100644 --- a/app/(app)/[username]/[slug]/page.tsx +++ b/app/(app)/[username]/[slug]/page.tsx @@ -13,6 +13,17 @@ import { parseUrlId, canonicalMismatch } from "@/server/lib/content-url"; import { serverApi } from "@/server/trpc/caller"; import { JsonLd } from "@/components/JsonLd"; import { getArticleSchema, getBreadcrumbSchema } from "@/lib/structured-data"; +import { ogPostImage } from "@/lib/og/url"; + +// Bare host for a link's "via {source}" chip, e.g. "anthropic.com". +const hostFromUrl = (value?: string | null): string | undefined => { + if (!value) return undefined; + try { + return new URL(value).hostname.replace(/^www\./, ""); + } catch { + return undefined; + } +}; type Props = { params: Promise<{ username: string; slug: string }> }; @@ -68,6 +79,7 @@ async function getUserPostUncached( authorImage: user.image, authorUsername: user.username, authorBio: user.bio, + authorJobTitle: user.jobTitle, }) .from(posts) .leftJoin(user, eq(posts.authorId, user.id)) @@ -111,6 +123,7 @@ async function getUserPostUncached( image: postRecord.authorImage, username: postRecord.authorUsername, bio: postRecord.authorBio, + jobTitle: postRecord.authorJobTitle, }, }; } @@ -145,6 +158,7 @@ async function getUserLinkPostUncached(username: string, postSlug: string) { authorImage: user.image, authorUsername: user.username, authorBio: user.bio, + authorJobTitle: user.jobTitle, }) .from(posts) .leftJoin(user, eq(posts.authorId, user.id)) @@ -182,6 +196,7 @@ async function getUserLinkPostUncached(username: string, postSlug: string) { image: linkPost.authorImage, username: linkPost.authorUsername, bio: linkPost.authorBio, + jobTitle: linkPost.authorJobTitle, }, }; } @@ -369,6 +384,16 @@ export async function generateMetadata(props: Props): Promise { } const tags = userPost.tags.map((tag) => tag.tag.title); const authorName = userPost.user.name || "Unknown"; + const postOgImage = ogPostImage({ + kind: "article", + title: userPost.title, + authorName, + authorRole: userPost.user.jobTitle, + authorKey: userPost.user.username ?? authorName, + tags, + readMins: userPost.readTimeMins, + updatedAt: userPost.updatedAt, + }); return { title: `${userPost.title} | by ${authorName} | Codú`, @@ -386,18 +411,13 @@ export async function generateMetadata(props: Props): Promise { url: `/${userPost.user.username ?? username}/${userPost.slug}`, publishedTime: userPost.published ?? undefined, modifiedTime: userPost.updatedAt ?? undefined, - images: [ - `/og?title=${encodeURIComponent( - userPost.title, - )}&readTime=${userPost.readTimeMins}&author=${encodeURIComponent( - authorName, - )}&date=${userPost.updatedAt}`, - ], + images: [postOgImage], siteName: "Codú", }, twitter: { + card: "summary_large_image", description: userPost.excerpt ?? undefined, - images: [`/og?title=${encodeURIComponent(userPost.title)}`], + images: [postOgImage], }, alternates: { // Cross-posted content points at the original; native posts @@ -413,6 +433,15 @@ export async function generateMetadata(props: Props): Promise { if (userArticle && userArticle.user) { const tags = userArticle.tags?.map((t) => t.tag.title) || []; const articleAuthorName = userArticle.user.name || "Unknown"; + const articleOgImage = ogPostImage({ + kind: "article", + title: userArticle.title, + authorName: articleAuthorName, + authorKey: userArticle.user.username ?? articleAuthorName, + tags, + readMins: userArticle.readTimeMins || 5, + updatedAt: userArticle.updatedAt, + }); return { title: `${userArticle.title} | by ${articleAuthorName} | Codú`, @@ -428,18 +457,13 @@ export async function generateMetadata(props: Props): Promise { url: `/${userArticle.user.username ?? username}/${userArticle.slug}`, publishedTime: userArticle.published ?? undefined, modifiedTime: userArticle.updatedAt ?? undefined, - images: [ - `/og?title=${encodeURIComponent( - userArticle.title, - )}&readTime=${userArticle.readTimeMins || 5}&author=${encodeURIComponent( - userArticle.user.name || "", - )}&date=${userArticle.updatedAt}`, - ], + images: [articleOgImage], siteName: "Codú", }, twitter: { + card: "summary_large_image", description: userArticle.excerpt || "", - images: [`/og?title=${encodeURIComponent(userArticle.title)}`], + images: [articleOgImage], }, alternates: { canonical: @@ -452,6 +476,17 @@ export async function generateMetadata(props: Props): Promise { const userLinkPost = await getUserLinkPost(username, slug); if (userLinkPost && userLinkPost.user) { const linkAuthorName = userLinkPost.user.name || "Unknown"; + const linkOgImage = ogPostImage({ + kind: "link", + title: userLinkPost.title, + authorName: linkAuthorName, + authorRole: userLinkPost.user.jobTitle, + authorKey: userLinkPost.user.username ?? linkAuthorName, + tags: userLinkPost.tags.map((t) => t.tag.title), + source: hostFromUrl(userLinkPost.externalUrl), + cover: userLinkPost.coverImage, + updatedAt: userLinkPost.updatedAt, + }); return { title: `${userLinkPost.title} | shared by ${linkAuthorName} | Codú`, @@ -463,9 +498,14 @@ export async function generateMetadata(props: Props): Promise { openGraph: { title: userLinkPost.title, description: userLinkPost.excerpt || `Link shared by ${linkAuthorName}`, - images: userLinkPost.coverImage ? [userLinkPost.coverImage] : undefined, + images: [linkOgImage], siteName: "Codú", }, + twitter: { + card: "summary_large_image", + description: userLinkPost.excerpt || `Link shared by ${linkAuthorName}`, + images: [linkOgImage], + }, // Member-shared links keep Codú as canonical (aggregated links point to source). alternates: { canonical: `/${userLinkPost.user.username ?? username}/${userLinkPost.slug}`, diff --git a/app/(app)/[username]/page.tsx b/app/(app)/[username]/page.tsx index af17250cd..79bcd9135 100644 --- a/app/(app)/[username]/page.tsx +++ b/app/(app)/[username]/page.tsx @@ -4,10 +4,11 @@ import Content from "./_usernameClient"; import { getServerAuthSession } from "@/server/auth"; import { type Metadata } from "next"; import { db } from "@/server/db"; -import { feed_sources } from "@/server/db/schema"; -import { eq, sql } from "drizzle-orm"; +import { feed_sources, follow } from "@/server/db/schema"; +import { count, eq, sql } from "drizzle-orm"; import { JsonLd } from "@/components/JsonLd"; import { getProfilePageSchema } from "@/lib/structured-data"; +import { ogProfileImage } from "@/lib/og/url"; type Props = { params: Promise<{ username: string }> }; @@ -18,9 +19,15 @@ export async function generateMetadata(props: Props): Promise { // Case-insensitive handle resolution (GitHub-style) on lower(username). const profile = await db.query.user.findFirst({ columns: { + id: true, bio: true, name: true, username: true, + location: true, + jobTitle: true, + topics: true, + createdAt: true, + updatedAt: true, }, where: (users) => sql`lower(${users.username}) = ${username.toLowerCase()}`, }); @@ -32,6 +39,23 @@ export async function generateMetadata(props: Props): Promise { const title = `${name || handle} (@${handle}) | Codú`; const description = `${name || handle}'s profile on Codú. ${bio ? `Bio: ${bio}` : "View their posts and contributions."}`; + const [followerRow] = await db + .select({ value: count() }) + .from(follow) + .where(eq(follow.followingId, profile.id)); + const joined = `Joined ${new Date(profile.createdAt).toLocaleString("en-US", { month: "short", year: "numeric" })}`; + const ogImage = ogProfileImage({ + name: name || handle, + key: handle, + role: profile.jobTitle, + location: profile.location, + bio, + followers: followerRow?.value ?? 0, + joined, + interests: profile.topics, + updatedAt: profile.updatedAt, + }); + return { title, description, @@ -44,7 +68,7 @@ export async function generateMetadata(props: Props): Promise { type: "profile", images: [ { - url: "/images/og/home-og.png", + url: ogImage, width: 1200, height: 630, alt: `${name || username}'s profile on Codú`, @@ -56,7 +80,7 @@ export async function generateMetadata(props: Props): Promise { card: "summary_large_image", title, description, - images: ["/images/og/home-og.png"], + images: [ogImage], }, }; } diff --git a/app/(app)/d/[slug]/page.tsx b/app/(app)/d/[slug]/page.tsx index dee4bbf54..a7bddbc3b 100644 --- a/app/(app)/d/[slug]/page.tsx +++ b/app/(app)/d/[slug]/page.tsx @@ -3,6 +3,7 @@ import { headers } from "next/headers"; import { notFound, permanentRedirect } from "next/navigation"; import { type Metadata } from "next"; import { SITE_ORIGIN } from "@/config/site"; +import { ogPostImage } from "@/lib/og/url"; import { getServerAuthSession } from "@/server/auth"; import { db } from "@/server/db"; import { posts, user, post_tags, tag, comments } from "@/server/db/schema"; @@ -171,6 +172,14 @@ export async function generateMetadata(props: Props): Promise { } const authorName = post.user.name || "Unknown"; + const ogImage = ogPostImage({ + kind: "discussion", + title: post.title, + authorName, + authorKey: post.user.username ?? authorName, + tags: post.tags.map((t) => t.tag.title), + updatedAt: post.updatedAt, + }); return { title: `${post.title} — Discussion | Codú`, @@ -187,15 +196,12 @@ export async function generateMetadata(props: Props): Promise { url: canonical, publishedTime: post.published ?? undefined, modifiedTime: post.updatedAt ?? undefined, - images: [ - `/og?title=${encodeURIComponent( - post.title, - )}&author=${encodeURIComponent(authorName)}&date=${post.updatedAt}`, - ], + images: [ogImage], }, twitter: { + card: "summary_large_image", description: post.excerpt ?? undefined, - images: [`/og?title=${encodeURIComponent(post.title)}`], + images: [ogImage], }, }; } diff --git a/app/(app)/discussions/page.tsx b/app/(app)/discussions/page.tsx index 517d62318..754caec18 100644 --- a/app/(app)/discussions/page.tsx +++ b/app/(app)/discussions/page.tsx @@ -1,19 +1,29 @@ import Content from "./_client"; import { getServerAuthSession } from "@/server/auth"; import { serverApi } from "@/server/trpc/caller"; +import { ogMainImage } from "@/lib/og/url"; + +const ogDescription = + "Ask questions, swap patterns, and get unstuck. The place to learn out loud with other builders working with AI."; +const ogImage = ogMainImage("discussions"); export const metadata = { title: "Discussions — Codú", - description: - "Ask questions, swap patterns, and get unstuck. The place to learn out loud with other builders working with AI.", + description: ogDescription, // Canonical to the bare path so ?sort/?filter param variants don't get indexed. alternates: { canonical: "/discussions" }, openGraph: { title: "Discussions — Codú", - description: - "Ask questions, swap patterns, and get unstuck. The place to learn out loud with other builders working with AI.", + description: ogDescription, type: "website", siteName: "Codú", + images: [ogImage], + }, + twitter: { + card: "summary_large_image", + title: "Discussions — Codú", + description: ogDescription, + images: [ogImage], }, }; diff --git a/app/(app)/jobs/[slug]/page.tsx b/app/(app)/jobs/[slug]/page.tsx index 52b870b1f..e2199ec51 100644 --- a/app/(app)/jobs/[slug]/page.tsx +++ b/app/(app)/jobs/[slug]/page.tsx @@ -1,10 +1,66 @@ +import { type Metadata } from "next"; +import { and, eq } from "drizzle-orm"; +import { db } from "@/server/db"; +import { job } from "@/server/db/schema"; +import { ogJobImage } from "@/lib/og/url"; import JobDetailClient from "./_client"; -export default async function JobDetailPage({ - params, -}: { - params: Promise<{ slug: string }>; -}) { - const { slug } = await params; +type Props = { params: Promise<{ slug: string }> }; + +const JOB_TYPE_LABEL: Record = { + "full-time": "Full-time", + "part-time": "Part-time", + freelancer: "Freelance", + other: "Contract", +}; + +export async function generateMetadata(props: Props): Promise { + const { slug } = await props.params; + + const [listing] = await db + .select() + .from(job) + .where(and(eq(job.slug, slug), eq(job.status, "active"))) + .limit(1); + + if (!listing) { + return { title: "Job Not Found" }; + } + + const title = `${listing.jobTitle} at ${listing.companyName} | Codú`; + const description = + `${listing.jobTitle} — ${listing.companyName}. ${listing.jobLocation}.`.trim(); + const ogImage = ogJobImage({ + company: listing.companyName, + role: listing.jobTitle, + location: listing.jobLocation, + jobType: JOB_TYPE_LABEL[listing.type] ?? "Full-time", + tags: listing.tags, + featured: listing.featured, + updatedAt: listing.updatedAt, + }); + + return { + title, + description, + alternates: { canonical: `/jobs/${listing.slug}` }, + openGraph: { + title, + description, + type: "website", + siteName: "Codú", + images: [ogImage], + }, + twitter: { + card: "summary_large_image", + title, + description, + images: [ogImage], + }, + }; +} + +export default async function JobDetailPage(props: Props) { + const { slug } = await props.params; return ; } diff --git a/app/(app)/jobs/page.tsx b/app/(app)/jobs/page.tsx index e6dd24212..106c13032 100644 --- a/app/(app)/jobs/page.tsx +++ b/app/(app)/jobs/page.tsx @@ -1,10 +1,25 @@ import type { Metadata } from "next"; import JobsClient from "./_client"; +import { ogMainImage } from "@/lib/og/url"; + +const ogDescription = + "Curated AI developer jobs — roles building with AI, LLMs, and agents. Remote, full-time, freelance, and more."; +const ogImage = ogMainImage("jobs"); export const metadata: Metadata = { title: "AI developer jobs — Codú", - description: - "Curated AI developer jobs — roles building with AI, LLMs, and agents. Remote, full-time, freelance, and more.", + description: ogDescription, + openGraph: { + title: "AI developer jobs — Codú", + description: ogDescription, + images: [ogImage], + }, + twitter: { + card: "summary_large_image", + title: "AI developer jobs — Codú", + description: ogDescription, + images: [ogImage], + }, }; export default function JobsPage() { diff --git a/app/(app)/s/[sourceSlug]/[slug]/page.tsx b/app/(app)/s/[sourceSlug]/[slug]/page.tsx index ba6c608f8..af99741d7 100644 --- a/app/(app)/s/[sourceSlug]/[slug]/page.tsx +++ b/app/(app)/s/[sourceSlug]/[slug]/page.tsx @@ -8,6 +8,7 @@ import { } from "@/lib/structured-data"; import { getFeedArticle, resolveAggregatedCanonical } from "./_resolvers"; import FeedArticleContent from "./_feedArticleContent"; +import { ogPostImage } from "@/lib/og/url"; type Props = { params: Promise<{ sourceSlug: string; slug: string }> }; @@ -19,17 +20,32 @@ export async function generateMetadata(props: Props): Promise { return { title: "Content Not Found" }; } + const description = + feedArticle.excerpt || `Discussion about ${feedArticle.title}`; + const ogImage = ogPostImage({ + kind: "link", + title: feedArticle.title, + authorName: + feedArticle.sourceAuthor || feedArticle.source.name || sourceSlug, + authorKey: feedArticle.source.slug || sourceSlug, + source: feedArticle.source.name, + cover: feedArticle.ogImageUrl || feedArticle.imageUrl, + updatedAt: feedArticle.updatedAt, + }); + return { title: `${feedArticle.title} | Codú Feed`, - description: feedArticle.excerpt || `Discussion about ${feedArticle.title}`, + description, openGraph: { title: feedArticle.title, - description: - feedArticle.excerpt || `Discussion about ${feedArticle.title}`, - images: - feedArticle.ogImageUrl || feedArticle.imageUrl - ? [feedArticle.ogImageUrl || feedArticle.imageUrl!] - : undefined, + description, + images: [ogImage], + }, + twitter: { + card: "summary_large_image", + title: feedArticle.title, + description, + images: [ogImage], }, alternates: { // Self-canonical: these are snippet + outbound-link listings (not full-body diff --git a/app/(app)/s/[sourceSlug]/_sourceProfileClient.tsx b/app/(app)/s/[sourceSlug]/_sourceProfileClient.tsx index 7e79fde76..0f985419a 100644 --- a/app/(app)/s/[sourceSlug]/_sourceProfileClient.tsx +++ b/app/(app)/s/[sourceSlug]/_sourceProfileClient.tsx @@ -7,6 +7,7 @@ import { toast } from "sonner"; import { api } from "@/server/trpc/react"; import { type RouterOutputs } from "@/server/trpc/shared"; import { UnifiedContentCard } from "@/components/UnifiedContentCard"; +import { hueFromString } from "@/utils/hue"; type SourceProfile = RouterOutputs["publication"]["getBySlug"]; @@ -18,14 +19,6 @@ type Props = { initialProfile: SourceProfile; }; -// Deterministic hue from the slug (sum of char codes mod 360). Math.random is -// unavailable here, and the publication tile colour must be stable per source. -const hueFromSlug = (slug: string): number => { - let sum = 0; - for (let i = 0; i < slug.length; i++) sum += slug.charCodeAt(i); - return sum % 360; -}; - // Two-letter initials for the square logo tile. const initialsFromName = (name: string): string => { const words = name.trim().split(/\s+/).filter(Boolean); @@ -91,7 +84,7 @@ const SourceProfileContent = ({ sourceSlug, initialProfile }: Props) => { ); } - const hue = hueFromSlug(pub.slug ?? sourceSlug); + const hue = hueFromString(pub.slug ?? sourceSlug); const initials = initialsFromName(pub.name); const isFollowing = optimisticFollowing ?? pub.isFollowing; diff --git a/app/(app)/s/[sourceSlug]/page.tsx b/app/(app)/s/[sourceSlug]/page.tsx index 145045453..f2cc058cd 100644 --- a/app/(app)/s/[sourceSlug]/page.tsx +++ b/app/(app)/s/[sourceSlug]/page.tsx @@ -3,6 +3,7 @@ import { notFound } from "next/navigation"; import { type Metadata } from "next"; import { getSourceProfile } from "./_resolvers"; import SourceProfileContent from "./_sourceProfileClient"; +import { ogPublicationImage } from "@/lib/og/url"; type Props = { params: Promise<{ sourceSlug: string }> }; @@ -15,15 +16,30 @@ export async function generateMetadata(props: Props): Promise { return { title: "Publication Not Found" }; } + const description = + source.tagline || `Articles from ${source.name} on Codú Feed`; + const ogImage = ogPublicationImage({ + name: source.name, + key: source.slug ?? sourceSlug, + tagline: source.tagline, + articleCount: source.articleCount, + followers: source.followerCount, + }); + return { title: `${source.name} | Codú Feed`, - description: source.tagline || `Articles from ${source.name} on Codú Feed`, + description, alternates: { canonical: `/s/${source.slug}` }, openGraph: { title: source.name, - description: - source.tagline || `Articles from ${source.name} on Codú Feed`, - images: source.logoUrl ? [source.logoUrl] : undefined, + description, + images: [ogImage], + }, + twitter: { + card: "summary_large_image", + title: source.name, + description, + images: [ogImage], }, }; } diff --git a/app/(app)/speakers/page.tsx b/app/(app)/speakers/page.tsx index 9e060433f..336925ce8 100644 --- a/app/(app)/speakers/page.tsx +++ b/app/(app)/speakers/page.tsx @@ -1,5 +1,8 @@ import type { Metadata } from "next"; import { SpeakersClient } from "./_client"; +import { ogMainImage } from "@/lib/og/url"; + +const OG_IMAGE = ogMainImage("home"); const PAGE_URL = "https://www.codu.co/speakers"; const PAGE_TITLE = "Speak at Codú — Pitch a Talk for Our Meetups"; @@ -24,11 +27,13 @@ export const metadata: Metadata = { description: PAGE_DESCRIPTION, url: PAGE_URL, type: "website", + images: [OG_IMAGE], }, twitter: { card: "summary_large_image", title: "Speak at Codú", description: PAGE_DESCRIPTION, + images: [OG_IMAGE], }, }; diff --git a/app/(app)/tag/[slug]/page.tsx b/app/(app)/tag/[slug]/page.tsx index f6f5d631f..129c8f72c 100644 --- a/app/(app)/tag/[slug]/page.tsx +++ b/app/(app)/tag/[slug]/page.tsx @@ -6,6 +6,7 @@ import { db } from "@/server/db"; import { posts, post_tags, tag, user, feed_sources } from "@/server/db/schema"; import { and, desc, eq, lte } from "drizzle-orm"; import { getCamelCaseFromLower } from "@/utils/utils"; +import { ogMainImage } from "@/lib/og/url"; type Props = { params: Promise<{ slug: string }>; @@ -114,6 +115,8 @@ export async function generateMetadata(props: Props): Promise { tagRow.description || `Articles, discussions, and resources tagged #${label} on Codú.`; + const ogImage = ogMainImage("articles"); + return { title, description, @@ -122,6 +125,13 @@ export async function generateMetadata(props: Props): Promise { title, description, siteName: "Codú", + images: [ogImage], + }, + twitter: { + card: "summary_large_image", + title, + description, + images: [ogImage], }, }; } diff --git a/app/(app)/volunteer/page.tsx b/app/(app)/volunteer/page.tsx index 27c6723c5..cd934163a 100644 --- a/app/(app)/volunteer/page.tsx +++ b/app/(app)/volunteer/page.tsx @@ -1,5 +1,8 @@ import type { Metadata } from "next"; import { VolunteerClient } from "./_client"; +import { ogMainImage } from "@/lib/og/url"; + +const OG_IMAGE = ogMainImage("home"); const PAGE_URL = "https://www.codu.co/volunteer"; const PAGE_TITLE = "Volunteer with Codú — Help grow our community"; @@ -25,11 +28,13 @@ export const metadata: Metadata = { description: PAGE_DESCRIPTION, url: PAGE_URL, type: "website", + images: [OG_IMAGE], }, twitter: { card: "summary_large_image", title: "Volunteer with Codú", description: PAGE_DESCRIPTION, + images: [OG_IMAGE], }, }; diff --git a/app/(marketing)/about/page.tsx b/app/(marketing)/about/page.tsx index d7c0850d7..b03514ac4 100644 --- a/app/(marketing)/about/page.tsx +++ b/app/(marketing)/about/page.tsx @@ -2,6 +2,9 @@ import type { Metadata } from "next"; import Link from "next/link"; import { Eyebrow, NewsletterCapture } from "@/components/ds"; import { twitterUrl, linkedinUrl } from "@/config/site_settings"; +import { ogMainImage } from "@/lib/og/url"; + +const ogImage = ogMainImage("about"); export const metadata: Metadata = { title: "About Codú — The community for AI builders & indie hackers", @@ -11,7 +14,14 @@ export const metadata: Metadata = { title: "About Codú — The community for AI builders & indie hackers", description: "Learn to build with AI, share what you ship, and grow with people doing the same. Free to join.", - images: "/images/og/home-og.png", + images: [ogImage], + }, + twitter: { + card: "summary_large_image", + title: "About Codú — The community for AI builders & indie hackers", + description: + "Learn to build with AI, share what you ship, and grow with people doing the same. Free to join.", + images: [ogImage], }, }; diff --git a/app/(marketing)/advertise/page.tsx b/app/(marketing)/advertise/page.tsx index 75da3a35a..dd857a971 100644 --- a/app/(marketing)/advertise/page.tsx +++ b/app/(marketing)/advertise/page.tsx @@ -2,11 +2,27 @@ import type { Metadata } from "next"; import { Eyebrow } from "@/components/ds"; import { AdvertiseTiers } from "@/components/Advertise/AdvertiseTiers"; import type { SponsorInterest } from "@/schema/sponsor"; +import { ogMainImage } from "@/lib/og/url"; + +const ogTitle = "Advertise with Codú — Reach a global community of AI builders"; +const ogDescription = + "Partner with Codú to reach a global community of AI builders and indie hackers. A few honest placements: a newsletter slot, a featured job, or an ongoing feed partnership."; +const ogImage = ogMainImage("advertise"); export const metadata: Metadata = { - title: "Advertise with Codú — Reach a global community of AI builders", - description: - "Partner with Codú to reach a global community of AI builders and indie hackers. A few honest placements: a newsletter slot, a featured job, or an ongoing feed partnership.", + title: ogTitle, + description: ogDescription, + openGraph: { + title: ogTitle, + description: ogDescription, + images: [ogImage], + }, + twitter: { + card: "summary_large_image", + title: ogTitle, + description: ogDescription, + images: [ogImage], + }, }; const tiers: { diff --git a/app/layout.tsx b/app/layout.tsx index 522126e69..a5178a9b0 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,6 @@ import { headers } from "next/headers"; import { SITE_ORIGIN } from "@/config/site"; +import { ogMainImage } from "@/lib/og/url"; import { getServerAuthSession } from "@/server/auth"; import "@/styles/globals.css"; import Fathom from "@/components/Fathom/Fathom"; @@ -78,7 +79,7 @@ export const metadata = { siteName: "Codú", images: [ { - url: `${SITE_ORIGIN}/images/og/home-og.png`, + url: ogMainImage("home"), width: 1200, height: 630, alt: "Codú — the community for AI builders & indie hackers", @@ -87,6 +88,13 @@ export const metadata = { locale: "en_US", type: "website", }, + twitter: { + card: "summary_large_image", + title: "Codú — The community for AI builders & indie hackers", + description: + "Codú is the community for AI builders and indie hackers. Learn to build with AI, share what you ship, and grow with people doing the same.", + images: [ogMainImage("home")], + }, }; export default async function RootLayout({ diff --git a/app/og/route.tsx b/app/og/route.tsx index 411f4d117..04d7042eb 100644 --- a/app/og/route.tsx +++ b/app/og/route.tsx @@ -1,216 +1,118 @@ +// Single dynamic OG endpoint for @vercel/og (next/og). All shareable pages +// point their openGraph/twitter images here via the builders in lib/og/url.ts. +// +// GET /og?type=main&id=home +// GET /og?type=post&kind=article&title=...&author=...&role=...&hue=200&read=6%20min&tags=RAG,evals&cover=https://... +// GET /og?type=profile&name=...&role=...&hue=200&location=...&bio=...&followers=3200&joined=...&interests=RAG,evals +// GET /og?type=publication&name=...&hue=184&tagline=...&articles=86&followers=12400 +// GET /og?type=job&company=...&logo=A&role=...&location=...&jobType=Full-time&tags=AI-native,LLM&featured=1 import { ImageResponse } from "next/og"; import * as Sentry from "@sentry/nextjs"; -import { Stars, Waves } from "@/components/background/background"; +import { OgImage, type OgParams } from "@/lib/og/templates"; +import { coduFonts } from "@/lib/og/fonts"; export const runtime = "edge"; +export const size = { width: 1200, height: 630 }; +export const contentType = "image/png"; -const height = 630; -const width = 1200; +// Edited records pass a `v` param, so cards can cache hard and indefinitely. +const CACHE_CONTROL = "public, immutable, no-transform, max-age=31536000"; -export async function GET(request: Request) { - try { - const { searchParams } = new URL(request.url); - const origin = `${request.headers.get("x-forwarded-proto") || "http"}://${request.headers.get("host")}`; - - const title = searchParams.get("title"); - const author = searchParams.get("author"); - const readTime = searchParams.get("readTime"); - const date = searchParams.get("date"); - - // Only the title is required — byline/meta lines render when provided, so - // title-only callers (e.g. twitter images) get a valid card, not a 500. - if (!title) { - throw new Error("Missing required parameter: title"); - } +// Load and reuse the font set per worker. +let _fonts: Awaited> | null = null; +const fonts = async () => (_fonts ??= await coduFonts()); - const metaLine = [ - date ? formatDate(date) : null, - readTime ? `${readTime} min read` : null, - ] - .filter(Boolean) - .join(" · "); - - const regularFontData = await fetch( - new URL("@/assets/Lato-Regular.ttf", import.meta.url), - ).then((res) => res.arrayBuffer()); - - const boldFontData = await fetch( - new URL("@/assets/Lato-Bold.ttf", import.meta.url), - ).then((res) => res.arrayBuffer()); - - return new ImageResponse( -
- - -
-
-
-
- planet - {/* Main content */} -
-
- Codu Logo -
-
-
- {title} -
-
-
- {author && ( -
- {author} -
- )} - {metaLine && ( -
- {metaLine} -
- )} -
-
-
-
-
, - { - fonts: [ - { - name: "Lato", - data: regularFontData, - style: "normal", - weight: 400, - }, - { - name: "Lato-Bold", - data: boldFontData, - style: "normal", - weight: 700, - }, - ], - height, - width, - }, - ); - } catch (err) { - Sentry.captureException(err); - return new Response(`Failed to generate the image`, { - status: 500, - }); - } +// Embed the wordmark as a data URI (fetched + cached once per worker) so Satori +// never has to resolve a same-origin mid-render — that fetch is flaky in +// local dev and adds a round-trip in prod. +let _logo: string | null = null; +async function logo(origin: string) { + if (_logo) return _logo; + const res = await fetch(`${origin}/og/wordmark-white.png`); + const bytes = new Uint8Array(await res.arrayBuffer()); + let binary = ""; + for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]); + return (_logo = `data:image/png;base64,${btoa(binary)}`); } -function formatDate(dateString: string): string { +const list = (v: string | null) => + v ? v.split(",").map((s) => s.trim()).filter(Boolean) : undefined; +const num = (v: string | null, d = 0) => (v != null && v !== "" ? Number(v) : d); + +export async function GET(req: Request) { try { - let date: Date; - if (dateString.includes(" ")) { - // Handle the specific format from the URL - const [datePart, timePart] = dateString.split(" "); - const [year, month, day] = datePart.split("-"); - const [time] = timePart.split("."); // Remove milliseconds - const isoString = `${year}-${month}-${day}T${time}Z`; - date = new Date(isoString); + const { searchParams: q, origin } = new URL(req.url); + const wordmark = await logo(origin); + const type = q.get("type") || "main"; + let params: OgParams; + + if (type === "post") { + params = { + type: "post", + kind: (q.get("kind") as "article" | "discussion" | "link") || "article", + title: q.get("title") || "Untitled", + author: { + name: q.get("author") || "Anonymous", + role: q.get("role") || "", + hue: num(q.get("hue"), 184), + }, + tags: list(q.get("tags")), + publication: q.get("pub") + ? { name: q.get("pub")!, hue: num(q.get("pubHue"), 184) } + : undefined, + source: q.get("source") || undefined, + read: q.get("read") || undefined, + cover: q.get("cover") || undefined, + logo: wordmark, + }; + } else if (type === "profile") { + params = { + type: "profile", + name: q.get("name") || "", + role: q.get("role") || "", + hue: num(q.get("hue"), 184), + location: q.get("location") || "", + bio: q.get("bio") || "", + topHelper: q.get("topHelper") === "1", + followers: num(q.get("followers")), + joined: q.get("joined") || "", + interests: list(q.get("interests")), + logo: wordmark, + }; + } else if (type === "publication") { + params = { + type: "publication", + name: q.get("name") || "", + hue: num(q.get("hue"), 184), + tagline: q.get("tagline") || "", + articleCount: num(q.get("articles")), + followers: num(q.get("followers")), + logo: wordmark, + }; + } else if (type === "job") { + params = { + type: "job", + company: q.get("company") || "", + logo: q.get("logo") || (q.get("company") || "?")[0], + role: q.get("role") || "", + location: q.get("location") || "", + jobType: q.get("jobType") || "Full-time", + salary: q.get("salary") || undefined, + tags: list(q.get("tags")), + featured: q.get("featured") === "1", + wordmark, + }; } else { - date = new Date(dateString); + params = { type: "main", id: q.get("id") || "home", logo: wordmark }; } - if (isNaN(date.getTime())) { - throw new Error("Invalid date"); - } - return date.toLocaleString("en-US", { - month: "long", - day: "numeric", - year: "numeric", + return new ImageResponse(OgImage(params), { + ...size, + fonts: await fonts(), + headers: { "cache-control": CACHE_CONTROL }, }); - } catch (error) { - return ""; + } catch (err) { + Sentry.captureException(err); + return new Response("Failed to generate the image", { status: 500 }); } } diff --git a/lib/og/fonts.ts b/lib/og/fonts.ts new file mode 100644 index 000000000..9f36b0314 --- /dev/null +++ b/lib/og/fonts.ts @@ -0,0 +1,48 @@ +// Font loading for the OG cards. Satori needs real binaries (TTF/OTF, not +// woff2). loadGoogleFont fetches a TTF slice from Google on demand, which works +// on the edge runtime with nothing to commit. Weights: Bricolage 800 (display), +// Hanken 400/600 (body), JetBrains Mono 400/600 (labels). + +type FontSpec = { + name: string; + data: ArrayBuffer; + weight: 400 | 600 | 700 | 800; + style: 'normal'; +}; + +// The css2 endpoint serves woff2 to modern UAs; spoofing an old UA makes it +// return a truetype url that Satori can parse. +export async function loadGoogleFont( + family: string, + weight: number, + text?: string, +): Promise { + const params = new URLSearchParams({ family: `${family}:wght@${weight}` }); + if (text) params.set('text', text); + const cssUrl = `https://fonts.googleapis.com/css2?${params.toString()}`; + const css = await fetch(cssUrl, { + headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 5.1)' }, // old UA → ttf + }).then((r) => r.text()); + const url = css.match(/src:\s*url\((.+?)\)\s*format\('(?:truetype|opentype)'\)/)?.[1]; + if (!url) throw new Error(`Could not resolve a TTF for ${family} ${weight}`); + return fetch(url).then((r) => r.arrayBuffer()); +} + +// Load everything Codú OG cards need. Pass it the text you're about to +// render to subset aggressively (smaller payloads); omit for full sets. +export async function coduFonts(text?: string): Promise { + const [bricolage, hanken400, hanken600, mono400, mono600] = await Promise.all([ + loadGoogleFont('Bricolage Grotesque', 800, text), + loadGoogleFont('Hanken Grotesk', 400, text), + loadGoogleFont('Hanken Grotesk', 600, text), + loadGoogleFont('JetBrains Mono', 400, text), + loadGoogleFont('JetBrains Mono', 600, text), + ]); + return [ + { name: 'Bricolage Grotesque', data: bricolage, weight: 800, style: 'normal' }, + { name: 'Hanken Grotesk', data: hanken400, weight: 400, style: 'normal' }, + { name: 'Hanken Grotesk', data: hanken600, weight: 600, style: 'normal' }, + { name: 'JetBrains Mono', data: mono400, weight: 400, style: 'normal' }, + { name: 'JetBrains Mono', data: mono600, weight: 600, style: 'normal' }, + ]; +} diff --git a/lib/og/templates.tsx b/lib/og/templates.tsx new file mode 100644 index 000000000..fd775b934 --- /dev/null +++ b/lib/og/templates.tsx @@ -0,0 +1,342 @@ +// Satori-safe card templates for the OG route. Flexbox only, every container +// has an explicit display/flexDirection, all colours are literal (see +// tokens.ts), no mask-image, and covers are real . OgImage(params) +// dispatches by `type`; each builder returns a 1200×630 element. +import React from 'react'; +import { T, FONT, avatarBg, pubBg, initials, fmtK } from './tokens'; + +const W = 1200; +const H = 630; + +// ---- shared style atoms -------------------------------------------- +const mono = (size: number, color: string = T.muted): React.CSSProperties => ({ + fontFamily: FONT.mono, fontSize: size, color, letterSpacing: '0.02em', +}); +const root = (pad = '72px 76px'): React.CSSProperties => ({ + width: W, height: H, position: 'relative', display: 'flex', flexDirection: 'column', + padding: pad, background: T.canvas, color: T.primary, fontFamily: FONT.sans, overflow: 'hidden', +}); +const spine: React.CSSProperties = { + position: 'absolute', left: 0, top: 0, bottom: 0, width: 6, background: T.accent, +}; +// faint radial glow stands in for the masked dot-grid (Satori-safe) +const glow: React.CSSProperties = { + position: 'absolute', top: -260, right: -200, width: 720, height: 720, borderRadius: 720, + background: 'radial-gradient(circle, rgba(45,212,191,0.10) 0%, rgba(45,212,191,0) 60%)', + display: 'flex', +}; +const topbar: React.CSSProperties = { + position: 'relative', display: 'flex', flexDirection: 'row', + alignItems: 'center', justifyContent: 'space-between', +}; +const url: React.CSSProperties = { ...mono(16, T.faint) }; + +function Wordmark({ src, h = 38 }: { src: string; h?: number }) { + // Explicit width (Satori ignores width:auto); ratio matches wordmark-white.png (1600×519). + const w = (h * 1600) / 519; + return Codú; +} +function Eyebrow({ label }: { label: string }) { + return ( +
+ {"//"} + {label} +
+ ); +} +function Tag({ children }: { children: React.ReactNode }) { + return ( +
+ {children} +
+ ); +} + +// ==================================================================== +// 1) MAIN-PAGE cards (static surfaces). hed is an array of lines. +// ==================================================================== +export const MAIN: Record = { + home: { eyebrow: 'The community for AI builders', hed: ['Learn to build with AI.', 'Ship what you make.'], sub: 'A knowledge-first community for web devs and indie hackers.' }, + about: { eyebrow: 'About Codú', hed: ['Less theory.', 'More shipping.'], sub: 'Why Codú exists, and who it’s for.' }, + articles: { eyebrow: 'Articles', hed: ['Guides and field notes', 'from people who ship.'], sub: 'Long-form from across the community.' }, + discussions:{ eyebrow: 'Discussions', hed: ['Ask, answer,', 'and figure it out together.'], sub: 'Questions, TILs and working notes from builders.' }, + jobs: { eyebrow: 'Jobs', hed: ['Roles for people', 'building with AI.'], sub: 'Hand-picked teams hiring right now.' }, + advertise: { eyebrow: 'Advertise', hed: ['Reach developers', 'who actually ship.'], sub: 'Sponsor the feed, the newsletter, the jobs board.' }, + weekly: { eyebrow: 'Codú Weekly', hed: ['The best of what', 'builders shipped.'], sub: 'One email a week. No fluff, no filler.' }, +}; + +export function MainCard({ id, logo }: { id: string; logo: string }) { + const c = MAIN[id] || MAIN.home; + return ( +
+
+
+
+ + codu.co +
+
+
+
+ {c.hed.map((line, i) => ( +
{line}
+ ))} +
+
{c.sub}
+
+
+ ); +} + +// ==================================================================== +// 2) POST card — adaptive (Article / Discussion / Link), cover or branded +// ==================================================================== +const KIND: Record = { + article: { label: 'Article', tone: 'neutral' }, + discussion: { label: 'Discussion', tone: 'info' }, + link: { label: 'Link', tone: 'faint' }, +}; + +export type PostParams = { + type: 'post'; + kind: 'article' | 'discussion' | 'link'; + title: string; + author: { name: string; role: string; hue: number }; + tags?: string[]; + publication?: { name: string; hue: number }; + source?: string; + read?: string; + cover?: string; // real image URL → cover layout; omit → branded + logo: string; +}; + +function KindBadge({ kind }: { kind: PostParams['kind'] }) { + const k = KIND[kind] || KIND.article; + const tone = + k.tone === 'info' ? { color: T.info, background: T.infoWash, border: 'none' } + : k.tone === 'neutral' ? { color: T.faint, background: 'transparent', border: `1px solid ${T.hairlineStrong}` } + : { color: T.faint, background: 'transparent', border: `1px solid ${T.hairline}` }; + return ( +
+ {k.label} +
+ ); +} + +function Chips({ p }: { p: PostParams }) { + return ( +
+ + {p.publication && ( +
+
+ {initials(p.publication.name)} +
+ {p.publication.name} +
+ )} + {p.source && ( +
+ via {p.source} + +
+ )} +
+ ); +} + +function Byline({ p }: { p: PostParams }) { + return ( +
+
+
+ {initials(p.author.name)} +
+
+ {p.author.name} + {p.author.role} +
+
+
+ {(p.tags || []).slice(0, 2).map((t) => {t})} + {p.kind === 'article' && p.read && {p.read} read} +
+
+ ); +} + +function Title({ text, size, lines }: { text: string; size: number; lines: number }) { + return ( +
+ {text} +
+ ); +} + +export function PostCard(p: PostParams) { + const hasCover = !!p.cover; + return ( +
+
+
+
+ + +
+ {hasCover ? ( +
+
+ + </div> + <img + src={p.cover} + width={384} + height={384} + alt="" + style={{ width: 384, height: '100%', objectFit: 'cover', borderRadius: 16, border: `1px solid ${T.hairlineStrong}` }} + /> + </div> + ) : ( + <div style={{ position: 'relative', display: 'flex', flex: 1, alignItems: 'center' }}> + <Title text={p.title} size={60} lines={3} /> + </div> + )} + <Byline p={p} /> + </div> + ); +} + +// ==================================================================== +// 3) IDENTITY cards — profile · publication · job +// ==================================================================== +function IdentityShell({ kicker, children, footLeft, logo }: { + kicker: React.ReactNode; children: React.ReactNode; footLeft: React.ReactNode; logo: string; +}) { + return ( + <div style={root()}> + <div style={glow} /> + <div style={spine} /> + <div style={topbar}>{kicker}<span style={url}>codu.co</span></div> + <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', marginTop: 'auto', gap: 30 }}> + {children} + </div> + <div style={{ position: 'relative', display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginTop: 'auto', paddingTop: 26, borderTop: `1px solid ${T.hairline}` }}> + {footLeft} + <Wordmark src={logo} h={30} /> + </div> + </div> + ); +} +function MintBadge({ children }: { children: React.ReactNode }) { + return ( + <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 6, fontFamily: FONT.mono, fontSize: 14, fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase', color: T.onAccent, background: T.accent, padding: '6px 13px', borderRadius: 999 }}> + {children} + </div> + ); +} +function MetaLine({ children }: { children: React.ReactNode }) { + return <div style={{ display: 'flex', flexDirection: 'row', ...mono(19, T.muted) }}>{children}</div>; +} +const metaB: React.CSSProperties = { color: T.accentSoft, fontWeight: 500 }; + +export type ProfileParams = { + type: 'profile'; name: string; role: string; hue: number; location: string; bio: string; + topHelper?: boolean; followers: number; joined: string; interests?: string[]; logo: string; +}; +export function ProfileCard(u: ProfileParams) { + return ( + <IdentityShell + logo={u.logo} + kicker={<Eyebrow label="PROFILE" />} + footLeft={<MetaLine><span style={metaB}>{fmtK(u.followers)}</span><span> followers · {u.joined}</span></MetaLine>} + > + <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 26 }}> + <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: 100, height: 100, borderRadius: 100, background: avatarBg(u.hue), fontFamily: FONT.display, fontWeight: 700, fontSize: 40, color: T.primary }}> + {initials(u.name)} + </div> + <div style={{ display: 'flex', flexDirection: 'column' }}> + <div style={{ fontFamily: FONT.display, fontWeight: 800, fontSize: 60, letterSpacing: '-0.03em', lineHeight: 1 }}>{u.name}</div> + <div style={{ ...mono(19, T.muted), marginTop: 12 }}>{[u.role, u.location].filter(Boolean).join(' · ')}</div> + </div> + </div> + <div style={{ color: T.muted, fontSize: 25, lineHeight: 1.45, maxWidth: 760, display: '-webkit-box', WebkitBoxOrient: 'vertical', WebkitLineClamp: 2, overflow: 'hidden' }}>{u.bio}</div> + <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 10 }}> + {u.topHelper && <MintBadge>★ Top helper</MintBadge>} + {(u.interests || []).slice(0, 3).map((t) => <Tag key={t}>{t}</Tag>)} + </div> + </IdentityShell> + ); +} + +export type PublicationParams = { + type: 'publication'; name: string; hue: number; tagline: string; articleCount: number; followers: number; logo: string; +}; +export function PublicationCard(p: PublicationParams) { + return ( + <IdentityShell + logo={p.logo} + kicker={<Eyebrow label="PUBLICATION" />} + footLeft={<MetaLine><span style={metaB}>{p.articleCount}</span><span> articles · </span><span style={metaB}>{fmtK(p.followers)}</span><span> followers</span></MetaLine>} + > + <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 26 }}> + <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: 100, height: 100, borderRadius: 12, background: pubBg(p.hue), fontFamily: FONT.display, fontWeight: 800, fontSize: 42, color: '#fff' }}> + {initials(p.name)} + </div> + <div style={{ fontFamily: FONT.display, fontWeight: 800, fontSize: 60, letterSpacing: '-0.03em', lineHeight: 1 }}>{p.name}</div> + </div> + <div style={{ color: T.muted, fontSize: 25, lineHeight: 1.45, maxWidth: 760, display: '-webkit-box', WebkitBoxOrient: 'vertical', WebkitLineClamp: 2, overflow: 'hidden' }}>{p.tagline}</div> + </IdentityShell> + ); +} + +export type JobParams = { + type: 'job'; company: string; logo: string; role: string; location: string; + jobType: string; salary?: string; tags?: string[]; featured?: boolean; wordmark: string; +}; +export function JobCard(j: JobParams) { + return ( + <IdentityShell + logo={j.wordmark} + kicker={ + <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 10 }}> + {j.featured && <MintBadge>Featured</MintBadge>} + <Eyebrow label="JOB" /> + </div> + } + footLeft={<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 10 }}>{(j.tags || []).slice(0, 3).map((t) => <Tag key={t}>{t}</Tag>)}</div>} + > + <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 18 }}> + <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: 64, height: 64, borderRadius: 8, background: T.elevated, border: `1px solid ${T.hairline}`, fontFamily: FONT.display, fontWeight: 800, fontSize: 26, color: T.primary }}> + {j.logo} + </div> + <div style={{ display: 'flex', ...mono(22, T.primary) }}>{j.company}</div> + </div> + <div style={{ fontFamily: FONT.display, fontWeight: 800, fontSize: 60, letterSpacing: '-0.03em', lineHeight: 1.02, maxWidth: 900, display: '-webkit-box', WebkitBoxOrient: 'vertical', WebkitLineClamp: 2, overflow: 'hidden' }}>{j.role}</div> + <MetaLine> + <span>{j.location} · {j.jobType}{j.salary ? ' · ' : ''}</span> + {j.salary && <span style={metaB}>{j.salary}</span>} + </MetaLine> + </IdentityShell> + ); +} + +// ==================================================================== +// DISPATCH — one entry point the route calls +// ==================================================================== +export type OgParams = + | ({ type: 'main'; id: string; logo: string }) + | PostParams + | ProfileParams + | PublicationParams + | JobParams; + +export function OgImage(params: OgParams): React.ReactElement { + switch (params.type) { + case 'main': return <MainCard id={params.id} logo={params.logo} />; + case 'post': return <PostCard {...params} />; + case 'profile': return <ProfileCard {...params} />; + case 'publication': return <PublicationCard {...params} />; + case 'job': return <JobCard {...params} />; + default: return <MainCard id="home" logo={(params as any).logo} />; + } +} diff --git a/lib/og/tokens.ts b/lib/og/tokens.ts new file mode 100644 index 000000000..9638ec17f --- /dev/null +++ b/lib/og/tokens.ts @@ -0,0 +1,43 @@ +// Design tokens for the OG cards, resolved to literals. Satori (inside +// next/og) can't read CSS custom properties or oklch(), so every colour is a +// plain hex/rgba/hsl string lifted from the design system. + +export const T = { + // canvas ladder + canvas: '#0a0b0e', + surface: '#121419', + elevated: '#181b22', + inset: '#08090c', + // borders + hairline: '#242832', + hairlineStrong: '#2f3440', + // text + primary: '#f4f6f8', + muted: '#9aa3b0', + faint: '#868f9b', + // accent (Mint) + accent: '#2dd4bf', + accentSoft: '#6ee7d6', + onAccent: '#04221d', + // status + info: '#5fa8f5', + infoWash: 'rgba(95,168,245,0.12)', +} as const; + +export const FONT = { + display: 'Bricolage Grotesque', + sans: 'Hanken Grotesk', + mono: 'JetBrains Mono', +} as const; + +// Avatar / publication-mark tints. The app uses oklch(0.5 0.08 H), which +// Satori can't parse, so these hsl values approximate it; the hue itself comes +// from the same hueFromString used on-site (see lib/og/url.ts). +export const avatarBg = (hue: number) => `hsl(${hue}, 22%, 42%)`; +export const pubBg = (hue: number) => `hsl(${hue}, 34%, 46%)`; + +export const initials = (name: string) => + name.split(' ').map((w) => w[0]).slice(0, 2).join(''); + +export const fmtK = (n: number) => + n >= 1000 ? (n / 1000).toFixed(1).replace('.0', '') + 'k' : '' + n; diff --git a/lib/og/url.ts b/lib/og/url.ts new file mode 100644 index 000000000..418565fe7 --- /dev/null +++ b/lib/og/url.ts @@ -0,0 +1,137 @@ +// Builders for the dynamic OG route (`app/og/route.tsx`). Each returns a +// relative `/og?...` URL; metadataBase (set in the root layout) resolves it to +// an absolute one. Param names here must match what the route reads. +import { hueFromString } from "@/utils/hue"; + +type Param = string | number | boolean | null | undefined; + +function ogUrl(params: Record<string, Param>): string { + const search = new URLSearchParams(); + for (const [key, value] of Object.entries(params)) { + if (value === undefined || value === null || value === "") continue; + search.set(key, String(value)); + } + return `/og?${search.toString()}`; +} + +// Cache-busting stamp so an edited record gets a fresh card (the route sets a +// long immutable cache-control). Seconds keep the URL short. +const version = (date?: string | Date | null): number | undefined => + date ? Math.floor(new Date(date).getTime() / 1000) : undefined; + +export type OgMainId = + | "home" + | "about" + | "advertise" + | "articles" + | "discussions" + | "jobs" + | "weekly"; + +export const ogMainImage = (id: OgMainId): string => ogUrl({ type: "main", id }); + +export type OgPostImageInput = { + kind: "article" | "discussion" | "link"; + title: string; + authorName: string; + authorRole?: string | null; + /** Stable key (username / source slug) the author hue is derived from. */ + authorKey: string; + tags?: string[]; + publicationName?: string | null; + publicationKey?: string | null; + source?: string | null; + readMins?: number | null; + cover?: string | null; + updatedAt?: string | Date | null; +}; + +export const ogPostImage = (post: OgPostImageInput): string => + ogUrl({ + type: "post", + kind: post.kind, + title: post.title, + author: post.authorName, + role: post.authorRole, + hue: hueFromString(post.authorKey), + tags: post.tags?.slice(0, 2).join(","), + pub: post.publicationName, + pubHue: post.publicationKey ? hueFromString(post.publicationKey) : undefined, + source: post.source, + read: post.readMins ? `${post.readMins} min` : undefined, + cover: post.cover, + v: version(post.updatedAt), + }); + +export type OgProfileImageInput = { + name: string; + /** Stable key (username) the avatar hue is derived from. */ + key: string; + role?: string | null; + location?: string | null; + bio?: string | null; + followers?: number; + joined?: string; + interests?: string[]; + topHelper?: boolean; + updatedAt?: string | Date | null; +}; + +export const ogProfileImage = (profile: OgProfileImageInput): string => + ogUrl({ + type: "profile", + name: profile.name, + hue: hueFromString(profile.key), + role: profile.role, + location: profile.location, + bio: profile.bio, + followers: profile.followers, + joined: profile.joined, + interests: profile.interests?.slice(0, 3).join(","), + topHelper: profile.topHelper ? 1 : undefined, + v: version(profile.updatedAt), + }); + +export type OgPublicationImageInput = { + name: string; + /** Stable key (slug) the publication-mark hue is derived from. */ + key: string; + tagline?: string | null; + articleCount?: number; + followers?: number; + updatedAt?: string | Date | null; +}; + +export const ogPublicationImage = (pub: OgPublicationImageInput): string => + ogUrl({ + type: "publication", + name: pub.name, + hue: hueFromString(pub.key), + tagline: pub.tagline, + articles: pub.articleCount, + followers: pub.followers, + v: version(pub.updatedAt), + }); + +export type OgJobImageInput = { + company: string; + role: string; + location: string; + jobType: string; + tags?: string[]; + featured?: boolean; + updatedAt?: string | Date | null; +}; + +export const ogJobImage = (jobListing: OgJobImageInput): string => + ogUrl({ + type: "job", + company: jobListing.company, + logo: jobListing.company.trim()[0]?.toUpperCase(), + role: jobListing.role, + location: jobListing.location, + jobType: jobListing.jobType, + tags: jobListing.tags?.slice(0, 3).join(","), + featured: jobListing.featured ? 1 : undefined, + v: version(jobListing.updatedAt), + }); diff --git a/lib/structured-data/schemas/article.ts b/lib/structured-data/schemas/article.ts index b390d27e9..ef53a6dcd 100644 --- a/lib/structured-data/schemas/article.ts +++ b/lib/structured-data/schemas/article.ts @@ -3,6 +3,7 @@ import { getOrganizationRef } from "./organization"; import { getPersonRef } from "./person"; import { SITE_ORIGIN as BASE_URL } from "@/config/site"; +import { ogPostImage } from "@/lib/og/url"; interface ArticleData { title: string; @@ -37,7 +38,15 @@ export function getArticleSchema( // image URL with article metadata. const ogImageUrl = article.image || - `${BASE_URL}/og?title=${encodeURIComponent(article.title)}&author=${encodeURIComponent(article.author.name || "")}&readTime=${article.readingTime || 5}&date=${article.updatedAt || article.publishedAt || ""}`; + `${BASE_URL}${ogPostImage({ + kind: "article", + title: article.title, + authorName: article.author.name || "Unknown", + authorKey: article.author.username || article.author.name || "Unknown", + tags: article.tags?.map((t) => t.title), + readMins: article.readingTime || 5, + updatedAt: article.updatedAt || article.publishedAt, + })}`; // Determine the canonical URL const mainEntityUrl = diff --git a/public/og/wordmark-white.png b/public/og/wordmark-white.png new file mode 100644 index 0000000000000000000000000000000000000000..2d2187c20fddbd943cd4fead6f9a639b4cc17125 GIT binary patch literal 77176 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 literal 0 HcmV?d00001 diff --git a/utils/hue.ts b/utils/hue.ts new file mode 100644 index 000000000..e6515fd6b --- /dev/null +++ b/utils/hue.ts @@ -0,0 +1,10 @@ +/** + * Deterministic hue (0–359) from a string. Used for avatar / publication tints + * so a given name or slug always maps to the same colour, on-site and in OG + * images. Math.random would break that stability across renders. + */ +export const hueFromString = (value: string): number => { + let sum = 0; + for (let i = 0; i < value.length; i++) sum += value.charCodeAt(i); + return sum % 360; +};