Integration Guides
Astro
Integrating OpenGraph.xyz with Astro is simple. You can construct the dynamic OG image URL directly in the frontmatter of your page and pass it to a <meta> tag.
URL Structure
The dynamic image URL follows this pattern:
https://ogcdn.net/{templateId}/v{version}/{variable1}/{variable2}/.../og.png
- templateId – your unique template identifier (found in the dashboard)
- version – the published version number, prefixed with
v(e.g.v3) - variables – URL-encoded values for each template variable, in order
Here is an example image generated with this URL structure:

URL Encoding
All variable values must be URL encoded. To use the default value for a variable, pass _ as the value for that segment. The version number updates every time you click "Publish" in the template editor.
Code Example
Below is an example for a blog post layout at src/layouts/BlogPost.astro. This example assumes a template with two variables: a title (text) and an image URL (image source).
---
const { title, description, heroImage } = Astro.props;
// Template details (find these in your dashboard)
const templateId = "4baf7dd9-4a11-4e55-9837-649e705f44ef";
const version = 3;
// Encode your variables
const encodedTitle = encodeURIComponent(title);
const encodedImage = encodeURIComponent(heroImage || "_");
// Construct the OG image URL
const ogImageUrl = `https://ogcdn.net/${templateId}/v${version}/${encodedTitle}/${encodedImage}/og.png`;
---
<head>
<title>{title}</title>
<meta name="description" content={description} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={ogImageUrl} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content={ogImageUrl} />
</head>
Replace the template ID and version number with the values from your dashboard. The variable segments must match the order defined in your template.
Dynamic Routes
For dynamic routes like src/pages/blog/[slug].astro, fetch your page data and encode the values the same way:
---
import { getEntry } from "astro:content";
const { slug } = Astro.params;
const post = await getEntry("blog", slug);
// Template details (find these in your dashboard)
const templateId = "4baf7dd9-4a11-4e55-9837-649e705f44ef";
const version = 3;
const encodedTitle = encodeURIComponent(post.data.title);
const encodedImage = encodeURIComponent(post.data.heroImage || "_");
const ogImageUrl = `https://ogcdn.net/${templateId}/v${version}/${encodedTitle}/${encodedImage}/og.png`;
---
<html>
<head>
<title>{post.data.title}</title>
<meta property="og:image" content={ogImageUrl} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content={ogImageUrl} />
</head>
<body>
<article>
<h1>{post.data.title}</h1>
</article>
</body>
</html>
Dashboard Integration Guides
In your OpenGraph.xyz dashboard, each template has a dedicated Integration tab with ready-to-copy code snippets that include your exact template ID, version, and variable names. Use those for the fastest setup.