diff --git a/apps/web/app/api/og/fonts.ts b/apps/web/app/api/og/fonts.ts new file mode 100644 index 0000000..840c932 --- /dev/null +++ b/apps/web/app/api/og/fonts.ts @@ -0,0 +1,19 @@ +import { readFile } from "fs/promises" +import { join } from "path" + +/** + * Loads Geist Mono font files for OG image generation. + * + * Font files are vendored into `public/fonts/` so they can be read via + * `process.cwd()` on Vercel (same pattern used by `public/icon.svg`). + * + * We can't read from `node_modules/geist/...` because in a monorepo + * dependencies are hoisted to the workspace root while `process.cwd()` + * points to the app directory (e.g. `apps/web`). + */ +const fontsDir = join(process.cwd(), "public", "fonts") + +export const geistMonoRegular = readFile( + join(fontsDir, "GeistMono-Regular.ttf") +) +export const geistMonoBold = readFile(join(fontsDir, "GeistMono-Bold.ttf")) diff --git a/apps/web/app/api/og/home/route.tsx b/apps/web/app/api/og/home/route.tsx index 4a4dd12..e0800a3 100644 --- a/apps/web/app/api/og/home/route.tsx +++ b/apps/web/app/api/og/home/route.tsx @@ -1,24 +1,13 @@ import { readFile } from "fs/promises" import { ImageResponse } from "next/og" import { join } from "path" +import { geistMonoBold, geistMonoRegular } from "@/app/api/og/fonts" const size = { width: 1200, height: 630, } -const geistMonoRegular = readFile( - join( - process.cwd(), - "node_modules/geist/dist/fonts/geist-mono/GeistMono-Regular.ttf" - ) -) -const geistMonoBold = readFile( - join( - process.cwd(), - "node_modules/geist/dist/fonts/geist-mono/GeistMono-Bold.ttf" - ) -) const iconSvg = readFile(join(process.cwd(), "public/icon.svg"), "utf-8") export async function GET() { diff --git a/apps/web/app/api/og/post/route.tsx b/apps/web/app/api/og/post/route.tsx index 48bcbf0..50c8ac7 100644 --- a/apps/web/app/api/og/post/route.tsx +++ b/apps/web/app/api/og/post/route.tsx @@ -1,8 +1,7 @@ import { and, eq } from "drizzle-orm" -import { readFile } from "fs/promises" import { ImageResponse } from "next/og" import type { NextRequest } from "next/server" -import { join } from "path" +import { geistMonoBold, geistMonoRegular } from "@/app/api/og/fonts" import { getRootCommentText } from "@/lib/data/posts" import { db } from "@/lib/db/client" import { posts } from "@/lib/db/schema" @@ -13,19 +12,6 @@ const size = { height: 630, } -const geistMonoRegular = readFile( - join( - process.cwd(), - "node_modules/geist/dist/fonts/geist-mono/GeistMono-Regular.ttf" - ) -) -const geistMonoBold = readFile( - join( - process.cwd(), - "node_modules/geist/dist/fonts/geist-mono/GeistMono-Bold.ttf" - ) -) - export async function GET(request: NextRequest) { const searchParams = request.nextUrl.searchParams const owner = searchParams.get("owner") diff --git a/apps/web/app/api/og/repo/route.tsx b/apps/web/app/api/og/repo/route.tsx index a022e8b..a2708c2 100644 --- a/apps/web/app/api/og/repo/route.tsx +++ b/apps/web/app/api/og/repo/route.tsx @@ -1,8 +1,7 @@ import { and, eq, sql } from "drizzle-orm" -import { readFile } from "fs/promises" import { ImageResponse } from "next/og" import type { NextRequest } from "next/server" -import { join } from "path" +import { geistMonoBold, geistMonoRegular } from "@/app/api/og/fonts" import { db } from "@/lib/db/client" import { posts } from "@/lib/db/schema" import { githubFetch } from "@/lib/github-fetch" @@ -13,19 +12,6 @@ const size = { height: 630, } -const geistMonoRegular = readFile( - join( - process.cwd(), - "node_modules/geist/dist/fonts/geist-mono/GeistMono-Regular.ttf" - ) -) -const geistMonoBold = readFile( - join( - process.cwd(), - "node_modules/geist/dist/fonts/geist-mono/GeistMono-Bold.ttf" - ) -) - interface GitHubRepoData { description: string | null [key: string]: unknown diff --git a/apps/web/app/api/og/user/route.tsx b/apps/web/app/api/og/user/route.tsx index 2ff6095..3b265ea 100644 --- a/apps/web/app/api/og/user/route.tsx +++ b/apps/web/app/api/og/user/route.tsx @@ -1,8 +1,7 @@ import { eq, sql } from "drizzle-orm" -import { readFile } from "fs/promises" import { ImageResponse } from "next/og" import type { NextRequest } from "next/server" -import { join } from "path" +import { geistMonoBold, geistMonoRegular } from "@/app/api/og/fonts" import { gitHubUserLoader } from "@/lib/auth" import { db } from "@/lib/db/client" import { comments } from "@/lib/db/schema" @@ -13,19 +12,6 @@ const size = { height: 630, } -const geistMonoRegular = readFile( - join( - process.cwd(), - "node_modules/geist/dist/fonts/geist-mono/GeistMono-Regular.ttf" - ) -) -const geistMonoBold = readFile( - join( - process.cwd(), - "node_modules/geist/dist/fonts/geist-mono/GeistMono-Bold.ttf" - ) -) - export async function GET(request: NextRequest) { const searchParams = request.nextUrl.searchParams const username = searchParams.get("username") diff --git a/apps/web/public/fonts/GeistMono-Bold.ttf b/apps/web/public/fonts/GeistMono-Bold.ttf new file mode 100644 index 0000000..170ad4e Binary files /dev/null and b/apps/web/public/fonts/GeistMono-Bold.ttf differ diff --git a/apps/web/public/fonts/GeistMono-Regular.ttf b/apps/web/public/fonts/GeistMono-Regular.ttf new file mode 100644 index 0000000..efa0b19 Binary files /dev/null and b/apps/web/public/fonts/GeistMono-Regular.ttf differ