How to Add Dynamic OG Images to Your Next.js App (2026 Guide)
The fastest way to get perfect social previews for every page in your Next.js application.
Why Dynamic OG Images?
If your Next.js app has dynamic content — blog posts, product pages, user profiles — you need unique OG images for each page. Static images don't cut it when you have hundreds or thousands of pages.
Method 1: Using an OG Image API (Fastest)
The simplest approach is to use an API like OGPix that generates images from URL parameters. No packages to install, no build configuration.
Step 1: Get your API key
Get a free API key — takes 5 seconds.
Step 2: Add to your layout or page metadata
// app/blog/[slug]/page.tsx
import type { Metadata } from "next";
type Props = { params: Promise<{ slug: string }> };
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params;
const post = await getPost(slug);
const ogUrl = new URL("https://ogpix-pi.vercel.app/api/og");
ogUrl.searchParams.set("title", post.title);
ogUrl.searchParams.set("description", post.excerpt);
ogUrl.searchParams.set("theme", "dark");
ogUrl.searchParams.set("key", process.env.OGPIX_KEY!);
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
images: [
{
url: ogUrl.toString(),
width: 1200,
height: 630,
},
],
},
twitter: {
card: "summary_large_image",
title: post.title,
description: post.excerpt,
images: [ogUrl.toString()],
},
};
}Step 3: Add your API key to environment variables
# .env.local OGPIX_KEY=og_live_your_key_here
That's it. Every blog post now gets a unique, beautiful social preview image.
Method 2: Using @vercel/og (Self-Hosted)
If you prefer to self-host your OG image generation, Next.js has built-in support via the @vercel/og package. This is what OGPix uses under the hood.
// app/api/og/route.tsx
import { ImageResponse } from "@vercel/og";
export const runtime = "edge";
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const title = searchParams.get("title") || "Default Title";
return new ImageResponse(
(
<div
style={{
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "linear-gradient(135deg, #667eea, #764ba2)",
fontSize: 64,
fontWeight: 800,
color: "white",
}}
>
{title}
</div>
),
{ width: 1200, height: 630 }
);
}This works well for simple cases, but you'll need to handle caching, rate limiting, usage analytics, and multiple templates yourself. That's the infrastructure OGPix handles for you.
Testing Your OG Images
After adding your meta tags, validate them with these tools:
- Twitter Card Validator: cards-dev.twitter.com/validator
- Facebook Sharing Debugger: developers.facebook.com/tools/debug
- LinkedIn Post Inspector: linkedin.com/post-inspector
- OpenGraph.xyz: Great for previewing across multiple platforms
Common Mistakes to Avoid
- Using relative URLs: OG image URLs must be absolute (start with https://)
- Missing width/height: Always include og:image:width and og:image:height for faster rendering
- Images too small: Use at least 1200x630 pixels for best results across platforms
- Text too long: Keep titles under 60 characters for best display
Try it now
Design your OG image in the playground and get the code for your Next.js app in seconds.
Open Playground →