Skip to content

Commit 2c61973

Browse files
techgangbossclaude
andcommitted
fix: add CDN caching to OG image (24hr), redirect old query param URLs
Twitter's crawler times out on edge cold starts (~3-4s). Adding Cache-Control: s-maxage=86400 so Vercel CDN caches the generated image for 24hrs. After first hit, subsequent requests (including Twitter's crawler) get served instantly from CDN edge. Also redirects old ?time= URLs to the clean /[time] path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 9243757 commit 2c61973

2 files changed

Lines changed: 8 additions & 170 deletions

File tree

src/app/api/og/preconfirm/[time]/route.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ export async function GET(
225225
{ name: "Clonoid", data: clonoidFont, style: "italic", weight: 700 },
226226
{ name: "Sora", data: soraFont, style: "normal", weight: 600 },
227227
],
228+
headers: {
229+
"Cache-Control": "public, max-age=86400, s-maxage=86400, stale-while-revalidate=604800",
230+
},
228231
}
229232
)
230233
}
Lines changed: 5 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -1,178 +1,13 @@
1-
import { ImageResponse } from "next/og"
2-
import { NextRequest } from "next/server"
1+
import { NextRequest, NextResponse } from "next/server"
32

43
export const runtime = "edge"
54

5+
/** Redirect old ?time= URLs to clean /api/og/preconfirm/[time] path */
66
export async function GET(request: NextRequest) {
77
const raw = parseFloat(request.nextUrl.searchParams.get("time") || "0.4")
88
const time = !isNaN(raw) && raw >= 0 && raw <= 999 ? raw.toFixed(1) : "0.4"
9-
10-
// Subsetted fonts: Clonoid digits-only (2.5KB), Sora label chars only (5KB)
11-
const [clonoidFont, soraFont] = await Promise.all([
12-
fetch(new URL("./fonts/clonoid-digits.ttf", import.meta.url)).then((r) =>
13-
r.arrayBuffer()
14-
),
15-
fetch(new URL("./fonts/sora-subset.ttf", import.meta.url)).then((r) =>
16-
r.arrayBuffer()
17-
),
18-
])
19-
20-
return new ImageResponse(
21-
<div
22-
style={{
23-
width: "100%",
24-
height: "100%",
25-
display: "flex",
26-
flexDirection: "column",
27-
alignItems: "center",
28-
justifyContent: "center",
29-
background: "linear-gradient(160deg, #020810 0%, #071428 35%, #0d2040 60%, #091830 100%)",
30-
position: "relative",
31-
overflow: "hidden",
32-
}}
33-
>
34-
{/* Outer subtle vignette */}
35-
<div
36-
style={{
37-
position: "absolute",
38-
inset: 0,
39-
background:
40-
"radial-gradient(ellipse 80% 70% at 50% 45%, transparent 30%, rgba(0,0,0,0.4) 100%)",
41-
}}
42-
/>
43-
44-
{/* Primary blue glow — centered upper half */}
45-
<div
46-
style={{
47-
position: "absolute",
48-
width: "800px",
49-
height: "500px",
50-
borderRadius: "50%",
51-
background:
52-
"radial-gradient(ellipse, rgba(20, 90, 200, 0.3) 0%, rgba(15, 70, 170, 0.12) 35%, transparent 65%)",
53-
top: "20%",
54-
left: "50%",
55-
transform: "translate(-50%, -50%)",
56-
}}
57-
/>
58-
59-
{/* Secondary smaller glow for depth */}
60-
<div
61-
style={{
62-
position: "absolute",
63-
width: "400px",
64-
height: "300px",
65-
borderRadius: "50%",
66-
background:
67-
"radial-gradient(ellipse, rgba(40, 130, 255, 0.15) 0%, transparent 70%)",
68-
top: "35%",
69-
left: "50%",
70-
transform: "translate(-50%, -50%)",
71-
}}
72-
/>
73-
74-
{/* Cyan horizon line */}
75-
<div
76-
style={{
77-
position: "absolute",
78-
width: "100%",
79-
height: "1px",
80-
top: "63%",
81-
background:
82-
"linear-gradient(90deg, transparent 5%, rgba(0, 180, 255, 0.15) 25%, rgba(0, 200, 255, 0.5) 50%, rgba(0, 180, 255, 0.15) 75%, transparent 95%)",
83-
}}
84-
/>
85-
86-
{/* Soft glow on the line */}
87-
<div
88-
style={{
89-
position: "absolute",
90-
width: "60%",
91-
height: "40px",
92-
top: "61.5%",
93-
left: "20%",
94-
background:
95-
"radial-gradient(ellipse, rgba(0, 160, 255, 0.08) 0%, transparent 70%)",
96-
}}
97-
/>
98-
99-
{/* Content */}
100-
<div
101-
style={{
102-
display: "flex",
103-
flexDirection: "column",
104-
alignItems: "center",
105-
justifyContent: "center",
106-
position: "relative",
107-
zIndex: 1,
108-
paddingBottom: "70px",
109-
}}
110-
>
111-
{/* SWAP PRECONFIRMED label */}
112-
<div
113-
style={{
114-
fontFamily: "Sora",
115-
fontSize: "22px",
116-
fontWeight: 600,
117-
color: "rgba(140, 190, 255, 0.45)",
118-
letterSpacing: "0.35em",
119-
textTransform: "uppercase" as const,
120-
marginBottom: "8px",
121-
}}
122-
>
123-
Swap Preconfirmed
124-
</div>
125-
126-
{/* Speed number + sec */}
127-
<div style={{ display: "flex", alignItems: "baseline", gap: "16px" }}>
128-
<div
129-
style={{
130-
fontFamily: "Clonoid",
131-
fontSize: "200px",
132-
color: "#fff",
133-
lineHeight: 1,
134-
letterSpacing: "-0.02em",
135-
}}
136-
>
137-
{time}
138-
</div>
139-
<div
140-
style={{
141-
fontFamily: "Sora",
142-
fontSize: "52px",
143-
fontWeight: 600,
144-
color: "rgba(140, 190, 255, 0.4)",
145-
lineHeight: 1,
146-
marginBottom: "20px",
147-
}}
148-
>
149-
sec
150-
</div>
151-
</div>
152-
153-
{/* Branding */}
154-
<div
155-
style={{
156-
fontFamily: "Sora",
157-
fontSize: "22px",
158-
fontWeight: 600,
159-
color: "rgba(140, 190, 255, 0.3)",
160-
marginTop: "24px",
161-
fontStyle: "italic",
162-
letterSpacing: "0.05em",
163-
}}
164-
>
165-
fastprotocol.io
166-
</div>
167-
</div>
168-
</div>,
169-
{
170-
width: 1200,
171-
height: 630,
172-
fonts: [
173-
{ name: "Clonoid", data: clonoidFont, style: "italic", weight: 700 },
174-
{ name: "Sora", data: soraFont, style: "normal", weight: 600 },
175-
],
176-
}
9+
return NextResponse.redirect(
10+
new URL(`/api/og/preconfirm/${time}`, request.url),
11+
301
17712
)
17813
}

0 commit comments

Comments
 (0)