Skip to content

Commit 799efc9

Browse files
committed
fix: add caching headers to Open Graph image generation for improved performance
1 parent 76cd28e commit 799efc9

File tree

6 files changed

+40
-7
lines changed

6 files changed

+40
-7
lines changed

app/[domain]/opengraph-image.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ export default async function OGImage({
173173
{
174174
...size,
175175
fonts,
176+
headers: {
177+
"Cache-Control": "public, max-age=604800, stale-while-revalidate=3600",
178+
"Vercel-CDN-Cache-Control":
179+
"max-age=604800, stale-while-revalidate=3600",
180+
},
176181
},
177182
);
178183
}

app/[domain]/page.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ export async function generateMetadata({
2020
const normalized = normalizeDomainInput(decoded);
2121

2222
return {
23-
title: `${normalized} — Domain Report`,
23+
title: {
24+
absolute: `${normalized} — Domain Report`,
25+
},
2426
description: `Domainstack report for ${normalized}: WHOIS lookup, DNS & SSL scan, HTTP headers, hosting & email provider data, and SEO metadata.`,
2527
alternates: {
2628
canonical: `/${normalized}`,

app/layout.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,23 @@ import { TRPCProvider } from "@/trpc/client";
1313
import "./globals.css";
1414

1515
export const metadata: Metadata = {
16-
title: "Domainstack — Domain Intelligence Made Easy",
16+
title: {
17+
default: "Domainstack — Domain Intelligence Made Easy",
18+
template: "%s — Domainstack",
19+
},
1720
description:
1821
"Unlock full domain intelligence in one tool. Instantly view registration history, DNS and SSL records, HTTP headers, hosting & email details, and live SEO signals — all in one clean, fast interface.",
1922
metadataBase: new URL(BASE_URL),
2023
alternates: {
2124
canonical: "/",
2225
},
26+
formatDetection: {
27+
telephone: false,
28+
date: false,
29+
address: false,
30+
email: false,
31+
url: false,
32+
},
2333
};
2434

2535
export default function RootLayout({

app/not-found.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { FileQuestionMark } from "lucide-react";
2+
import type { Metadata } from "next";
23
import { DomainSearch } from "@/components/domain/domain-search";
34
import {
45
Empty,
@@ -9,6 +10,11 @@ import {
910
EmptyTitle,
1011
} from "@/components/ui/empty";
1112

13+
export const metadata: Metadata = {
14+
title: "Not Found",
15+
description: "The page you're looking for doesn't exist.",
16+
};
17+
1218
export default function NotFound() {
1319
return (
1420
<div className="container mx-auto my-auto flex items-center justify-center px-6">

app/opengraph-image.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ export default async function OGImage() {
143143
{
144144
...size,
145145
fonts,
146+
headers: {
147+
"Cache-Control": "public, max-age=604800, stale-while-revalidate=3600",
148+
"Vercel-CDN-Cache-Control":
149+
"max-age=604800, stale-while-revalidate=3600",
150+
},
146151
},
147152
);
148153
}

lib/opengraph-image.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import fs from "node:fs/promises";
22
import path from "node:path";
3+
import { cacheLife } from "next/cache";
34

45
// ── Brand palette
56
export const BRAND = {
@@ -57,20 +58,24 @@ async function loadGeistFromPackage() {
5758
}
5859
}
5960

60-
async function fetchGoogleWoff2(cssUrl: string, revalidateSec = 60 * 60 * 24) {
61-
const cssRes = await fetch(cssUrl, { next: { revalidate: revalidateSec } });
61+
async function fetchGoogleWoff2(cssUrl: string) {
62+
"use cache";
63+
cacheLife("max");
64+
65+
const cssRes = await fetch(cssUrl);
6266
if (!cssRes.ok) throw new Error(`Font CSS fetch failed: ${cssUrl}`);
6367
const css = await cssRes.text();
6468
const match = css.match(/src:\s*url\((https:[^)]+\.woff2)\)/);
6569
if (!match?.[1]) throw new Error(`No .woff2 URL found in CSS: ${cssUrl}`);
66-
const fontRes = await fetch(match[1], {
67-
next: { revalidate: revalidateSec },
68-
});
70+
const fontRes = await fetch(match[1]);
6971
if (!fontRes.ok) throw new Error(`Font binary fetch failed: ${match[1]}`);
7072
return fontRes.arrayBuffer();
7173
}
7274

7375
async function loadGeistFromGoogle() {
76+
"use cache";
77+
cacheLife("max");
78+
7479
try {
7580
const regular = await fetchGoogleWoff2(
7681
"https://fonts.googleapis.com/css2?family=Geist:wght@400&display=swap",

0 commit comments

Comments
 (0)