Prismic Open Graph Tags: Add OG Meta to Your Prismic CMS Site
How to add og:title, og:image, and og:description to Prismic-powered sites — with Image fields, slice metadata, and Next.js generateMetadata integration.
Prismic and OG metadata architecture
Prismic is a headless CMS used for marketing sites, blogs, and landing pages. Like all headless CMSs, OG tags are rendered in the frontend layer — not Prismic itself. Your Next.js, Nuxt, or SvelteKit app queries Prismic's API and generates the <meta> tags.
Prismic has a built-in concept for this: SEO fields in your Custom Type definition. The standard pattern is to add a "SEO & Social" group field with title, description, and image.
Step 1: Add SEO fields to your Prismic Custom Type
In the Prismic Custom Type editor (or customtypes/ JSON), add an SEO group:
// customtypes/blog_post/index.json (relevant section)
{
"SEO": {
"seo_title": {
"type": "StructuredText",
"config": {
"single": "paragraph",
"label": "SEO Title",
"placeholder": "Leave blank to use the post title"
}
},
"seo_description": {
"type": "StructuredText",
"config": {
"single": "paragraph",
"label": "SEO Description"
}
},
"seo_image": {
"type": "Image",
"config": {
"label": "OG / Social Share Image",
"constraint": {
"width": 1200,
"height": 630
},
"thumbnails": []
}
}
}
}Setting constraint: width/height on the image field tells Prismic to validate the dimensions — editors will see a warning if they upload the wrong size.
Step 2: Query and render OG metadata in Next.js
// app/blog/[uid]/page.tsx
import type { Metadata } from "next";
import { createClient } from "@/prismicio";
import { asText, asImageSrc } from "@prismicio/client";
export async function generateMetadata({
params,
}: {
params: { uid: string };
}): Promise<Metadata> {
const client = createClient();
const doc = await client.getByUID("blog_post", params.uid);
if (!doc) return { title: "Not Found" };
// Prefer explicit SEO fields; fall back to content fields
const title = doc.data.seo_title
? asText(doc.data.seo_title)
: asText(doc.data.title);
const description = doc.data.seo_description
? asText(doc.data.seo_description)
: doc.data.excerpt
? asText(doc.data.excerpt)
: "";
// Prefer SEO image; fall back to featured image
const ogImage = doc.data.seo_image?.url || doc.data.featured_image?.url;
return {
title,
description,
openGraph: {
title,
description,
type: "article",
images: ogImage
? [
{
url: ogImage,
width: doc.data.seo_image?.dimensions?.width || 1200,
height: doc.data.seo_image?.dimensions?.height || 630,
},
]
: [],
},
twitter: {
card: "summary_large_image",
title,
description,
images: ogImage ? [ogImage] : [],
},
};
}Using Prismic Image fields for OG images
Prismic Image fields include built-in responsive transforms. Use them to get exactly the right size for OG:
import { asImageSrc } from "@prismicio/client";
// Get URL with specific dimensions
const ogImageUrl = asImageSrc(doc.data.seo_image, {
w: 1200,
h: 630,
fit: "crop",
auto: "format",
q: 85,
});
// Prismic Imgix URL format:
// https://images.prismic.io/repo/image.jpg?auto=format&fit=crop&w=1200&h=630
// In metadata:
images: ogImageUrl
? [{ url: ogImageUrl, width: 1200, height: 630 }]
: [],Slice-based pages and OG fallbacks
For Prismic slice-based pages (landing pages, etc.), there may be no obvious OG image in the content. Set up a fallback hierarchy:
function resolveOgImage(doc: PrismicDocument): string {
// 1. Explicit SEO image field
if (doc.data.seo_image?.url) {
return asImageSrc(doc.data.seo_image, { w: 1200, h: 630, fit: "crop" })!;
}
// 2. First hero image found in slices
for (const slice of doc.data.slices || []) {
if (slice.variation === "default" && slice.primary?.background_image?.url) {
return asImageSrc(slice.primary.background_image, {
w: 1200,
h: 630,
fit: "crop",
})!;
}
}
// 3. Dynamic generated OG image
const title = asText(doc.data.seo_title || doc.data.title);
return `/api/og?title=${encodeURIComponent(title)}`;
}Common Prismic OG pitfalls
- asText() for titles: Prismic StructuredText fields return an array — always use
asText()to extract plain string - Image URL expiry: Prismic image URLs via Imgix don't expire, but ensure no CDN rewrite strips transform params
- Draft content: Prismic drafts are only accessible with preview tokens — ensure social scrapers get published content
- Missing content-type: Always wrap
generateMetadatain try/catch for unpublished UIDs
Preview your Prismic OG tags
After deploying, paste any page URL into OGFixer to see exactly how your social previews appear on Twitter, LinkedIn, Discord, and Slack.
Check your OG tags free →