Next.js: Dynamic OG Images + Short Links
1) Add an OG image route
Create app/api/og/route.ts
(App Router). This example renders a simple PNG using ImageResponse
.
/* app/api/og/route.ts */
import { ImageResponse } from "next/og";
export const runtime = "edge";
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const title = searchParams.get("title") || "My Product";
return new ImageResponse(
(
<div
style={{
height: "100%",
width: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "white",
fontSize: 64,
fontWeight: 700,
textAlign: "center",
padding: 60
}}
>
{title}
</div>
),
{ width: 1200, height: 630 }
);
}
2) Point a page’s OG image at that route
In a product page like app/products/[slug]/page.tsx
:
/* app/products/[slug]/page.tsx */
type Props = { params: { slug: string } };
export async function generateMetadata({ params }: Props) {
const product = await getProduct(params.slug); // your data layer
const og = `https://yourdomain.com/api/og?title=${encodeURIComponent(product.name)}`;
return {
title: product.name,
description: product.summary,
openGraph: {
title: product.name,
description: product.summary,
images: [{ url: og, width: 1200, height: 630, alt: product.name }]
},
twitter: { card: "summary_large_image" }
};
}
export default async function Page({ params }: Props) {
const product = await getProduct(params.slug);
return (<main><h1>{product.name}</h1></main>);
}
3) (Optional) Use a short link per campaign
Create a short link that overrides OG for a campaign (you can rotate creatives later without redeploying Next.js):
# cURL example — adjust fields to your API
curl -X POST https://api.ogli.sh/link \
-H "Authorization: Bearer $OGLI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourdomain.com/products/superwidget",
"alias": "superwidget-launch",
"og": {
"title": "SuperWidget — Launch Day",
"description": "Ships today. Free returns.",
"image": "https://yourdomain.com/api/og?title=SuperWidget%20Launch"
}
}'
Share https://ogli.sh/superwidget-launch
. To update the card after launch, swap the OG image or bump a querystring (e.g., ?v=2
).
4) Testing & tips
- Ensure your OG route returns 1200×630 quickly (<1–2s).
- Edge runtime has memory limits—keep your image composition simple, host big fonts/images on a CDN.
- When changing OG images, version the URL so platforms refetch.
Troubleshooting
- Blank card: check that the OG route is publicly reachable and returns a 200 with an image.
- Wrong crop: keep critical text large with generous margins.
- Stale preview: add
?v=2
to the image URL and re-share.