Generating Social & OpenGraph Images with Imgwire
Social preview images need fixed dimensions, predictable crops, and stable public URLs. Imgwire transformations let you create those variants from the same uploaded source image you use elsewhere in your app.
This tutorial uses 1200 by 630 images for OpenGraph and Twitter/X summary cards.
Create a social image URL
If you already have an Imgwire image record, generate a social variant with a fixed size and crop behavior:
const socialImageUrl = image.url({
width: 1200,
height: 630,
resizing_type: 'cover',
gravity: 'attention',
format: 'jpeg',
quality: 85,
});
Use format=jpeg when the consumer expects a broadly compatible social image. Use format=auto for normal browser display.
The raw URL shape looks like this:
https://cdn.imgwire.dev/{organization_id}/{environment_id}/{image_id}?width=1200&height=630&resizing_type=cover&gravity=attention&format=jpeg&quality=85
Add to Next.js metadata
In a Next.js App Router page, retrieve the Imgwire image by ID and return the generated URL from generateMetadata.
import type { Metadata } from 'next';
import { ImgwireClient } from '@imgwire/node';
const imgwire = new ImgwireClient({
apiKey: process.env.IMGWIRE_API_KEY!,
});
type PageProps = {
params: { slug: string };
};
export async function generateMetadata({
params,
}: PageProps): Promise<Metadata> {
const post = await getPostBySlug(params.slug);
const image = await imgwire.images.retrieve(post.heroImageId);
const ogImageUrl = image.url({
width: 1200,
height: 630,
resizing_type: 'cover',
gravity: 'attention',
format: 'jpeg',
quality: 85,
});
return {
title: post.title,
description: post.description,
openGraph: {
title: post.title,
description: post.description,
images: [
{
url: ogImageUrl,
width: 1200,
height: 630,
alt: post.title,
},
],
},
twitter: {
card: 'summary_large_image',
title: post.title,
description: post.description,
images: [ogImageUrl],
},
};
}
The metadata function runs on the server, so it can safely use a Server API Key.
Use an uploaded template image
A common workflow is to generate a social card template in your CMS or design system, upload it to Imgwire, and create variants from that source:
const image = await imgwire.images.upload({
file: templateBuffer,
fileName: `${post.slug}-social-card.png`,
mimeType: 'image/png',
purpose: 'social preview image',
customMetadata: {
post_slug: post.slug,
template: 'blog-social-card-v1',
},
});
Then store image.id on the post. You can regenerate the social URL later without re-uploading the template.
Crop existing images safely
When using normal content images as social previews, use a fixed crop:
image.url({
width: 1200,
height: 630,
resizing_type: 'cover',
gravity: 'attention',
format: 'jpeg',
quality: 85,
});
gravity=attention is useful for uploaded photos and AI-generated images where the subject may not be centered. Use a manual crop when your content system already knows the exact region to use.
Cache social URLs
Social crawlers request the same image multiple times. Keep the generated URL stable for each page version:
- Store the Imgwire image ID with the content record.
- Keep the transformation parameters consistent.
- Avoid cache-busting query parameters unless the content actually changed.
- Regenerate the source image or change the stored ID when the social card design changes.
Best practices
- Use 1200 by 630 for general OpenGraph images.
- Use explicit dimensions and crop behavior.
- Use JPEG for broad social crawler compatibility unless your workflow needs another format.
- Include meaningful alt text in OpenGraph metadata where your framework supports it.
- Test the final public URL before publishing pages.
Related pages
Last updated at: May 8, 2026