Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 139 additions & 9 deletions app/docs-og/[...slug]/route.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,146 @@
import { metadataImage } from "@/lib/docs/metadata";
import { generateOGImage } from "fumadocs-ui/og";
import { ImageResponse } from "next/og";
import React from "react";
import fs from "node:fs";
import path from "node:path";

export const dynamic = "force-dynamic";
Comment on lines +3 to 7
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This route now imports node:fs/node:path but does not pin runtime = "nodejs". The rest of the codebase explicitly sets Node runtime for ImageResponse routes (e.g., app/banner/route.tsx:3). Add export const runtime = "nodejs"; here to avoid accidental Edge runtime execution where fs isn’t available.

Copilot uses AI. Check for mistakes.

export const GET = metadataImage.createAPI((page) => {
return generateOGImage({
title: page.data.title,
description: page.data.description,
site: "FixFX",
primaryColor: "#3b82f6",
primaryTextColor: "#f8fafc",
});
export const GET = metadataImage.createAPI(async (page: any) => {
// Truncate description to prevent overflow
const maxDescLength = 150;
const description = page.data.description
? page.data.description.length > maxDescLength
? page.data.description.substring(0, maxDescLength).trim() + "..."
: page.data.description
: "";

// Read the logo from the filesystem
const logoPath = path.join(process.cwd(), "public", "logo.png");
const logoBuffer = fs.readFileSync(logoPath);
const logoData = logoBuffer.buffer.slice(logoBuffer.byteOffset, logoBuffer.byteOffset + logoBuffer.byteLength);
Comment on lines +18 to +21
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fs.readFileSync is executed on every request. Since the logo is static, consider loading/caching it at module scope (or memoizing) so dynamic OG requests don’t repeatedly hit the filesystem.

Copilot uses AI. Check for mistakes.

return new ImageResponse(
(
<div
style={{
width: "100%",
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
justifyContent: "space-between",
background: "linear-gradient(to bottom right, #0a0a0f 0%, #0d0d14 50%, #0f0f18 100%)",
position: "relative",
overflow: "hidden",
padding: "60px 80px",
}}
>
{/* Background gradient orbs */}
<div
style={{
position: "absolute",
top: "-100px",
left: "200px",
width: "400px",
height: "400px",
background: "radial-gradient(circle, rgba(59, 130, 246, 0.2) 0%, transparent 70%)",
borderRadius: "50%",
}}
/>
<div
style={{
position: "absolute",
bottom: "-50px",
right: "150px",
width: "350px",
height: "350px",
background: "radial-gradient(circle, rgba(139, 92, 246, 0.15) 0%, transparent 70%)",
borderRadius: "50%",
}}
/>

{/* Header with logo and site name */}
<div
style={{
display: "flex",
alignItems: "center",
gap: "20px",
zIndex: 10,
}}
>
<img
// @ts-ignore
src={logoData as any}
alt="Logo"
Comment on lines +72 to +75
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid // @ts-ignore/as any for the <img src>. Prefer providing a type-safe src (e.g., a data URL string) or using a supported binary type with an explicit, narrow cast so type errors aren’t masked.

Copilot uses AI. Check for mistakes.
width="64"
height="64"
style={{
borderRadius: "12px",
}}
/>
<span
style={{
fontSize: "48px",
fontWeight: 800,
background: "linear-gradient(to right, #3b82f6, #06b6d4)",
backgroundClip: "text",
color: "transparent",
letterSpacing: "-0.02em",
}}
>
FixFX
</span>
</div>

{/* Main content */}
<div
style={{
display: "flex",
flexDirection: "column",
gap: "24px",
maxWidth: "1100px",
zIndex: 10,
}}
>
<h1
style={{
fontSize: "100px",
fontWeight: 900,
background: "linear-gradient(to bottom right, #ffffff 30%, #94a3b8 100%)",
backgroundClip: "text",
color: "transparent",
lineHeight: 1.0,
margin: 0,
letterSpacing: "-0.04em",
}}
>
{page.data.title}
</h1>
{description && (
<p
style={{
fontSize: "32px",
fontWeight: 400,
color: "#94a3b8",
lineHeight: 1.4,
margin: 0,
letterSpacing: "-0.01em",
}}
>
{description}
</p>
)}
</div>


</div>
),
{
width: 1200,
height: 630,
}
);
});

export function generateStaticParams() {
Expand Down
Loading
Loading