Astro Starlight Open Graph Tags: Add OG Meta to Your Docs
How to add og:title, og:image, and og:description to Astro Starlight documentation sites — with site config, frontmatter overrides, and custom OG images.
Starlight's built-in OG support
Astro Starlight (Astro's official documentation theme) has built-in OG support starting from version 0.14. It auto-generates og:title andog:description from your page title and frontmatter description. For og:image, you need a small amount of configuration.
Step 1: Set a default OG image in astro.config.mjs
// astro.config.mjs
import { defineConfig } from "astro/config";
import starlight from "@astrojs/starlight";
export default defineConfig({
integrations: [
starlight({
title: "My Docs",
social: {
github: "https://github.com/yourusername/yourrepo",
},
// Default OG/social image for all pages
// Place file at: public/og-default.png (1200×630)
head: [
{
tag: "meta",
attrs: {
property: "og:image",
content: "https://docs.example.com/og-default.png",
},
},
{
tag: "meta",
attrs: {
property: "og:image:width",
content: "1200",
},
},
{
tag: "meta",
attrs: {
property: "og:image:height",
content: "630",
},
},
{
tag: "meta",
attrs: { name: "twitter:card", content: "summary_large_image" },
},
],
}),
],
site: "https://docs.example.com",
});Step 2: Per-page OG overrides via frontmatter
Override OG tags on individual pages using the head frontmatter key:
---
title: Getting Started
description: How to install and configure in 5 minutes.
head:
- tag: meta
attrs:
property: og:image
content: "https://docs.example.com/og/getting-started.png"
- tag: meta
attrs:
property: og:image:width
content: "1200"
- tag: meta
attrs:
property: og:image:height
content: "630"
---
# Getting Started
...Step 3: Auto-generate OG images with @astrojs/og (Satori)
For dynamic per-page OG images, use an Astro API endpoint with Satori:
// src/pages/og/[...slug].png.ts
import type { APIRoute } from "astro";
import { Resvg } from "@resvg/resvg-js";
import satori from "satori";
import { getCollection } from "astro:content";
export async function GET({ params }: { params: { slug: string } }) {
const slug = params.slug || "";
// Load the docs page data
const docs = await getCollection("docs");
const page = docs.find((p) => p.slug === slug);
const title = page?.data.title || "Docs";
// Generate SVG with Satori
const svg = await satori(
{
type: "div",
props: {
style: {
display: "flex",
flexDirection: "column",
background: "#0f172a",
width: "100%",
height: "100%",
padding: "60px 80px",
justifyContent: "flex-end",
},
children: [
{
type: "div",
props: {
style: { fontSize: 60, fontWeight: 900, color: "#fff", lineHeight: 1.2 },
children: title,
},
},
{
type: "div",
props: {
style: { fontSize: 28, color: "#6366f1", marginTop: 24 },
children: "docs.example.com",
},
},
],
},
},
{
width: 1200,
height: 630,
fonts: [
{
name: "Inter",
data: await fetch(
"https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiA.woff2"
).then((r) => r.arrayBuffer()),
weight: 900,
},
],
}
);
// Convert SVG to PNG
const resvg = new Resvg(svg, { fitTo: { mode: "width", value: 1200 } });
const png = resvg.render().asPng();
return new Response(png, {
headers: {
"Content-Type": "image/png",
"Cache-Control": "public, max-age=604800",
},
});
}
// Generate static paths for all docs pages
export async function getStaticPaths() {
const docs = await getCollection("docs");
return docs.map((page) => ({ params: { slug: page.slug } }));
}Starlight OG plugin (community)
The community plugin starlight-og automates dynamic OG image generation for all Starlight pages:
npm install starlight-og
// astro.config.mjs
import starlight from "@astrojs/starlight";
import starlightOg from "starlight-og";
export default defineConfig({
integrations: [
starlight({
plugins: [starlightOg()],
// ...
}),
],
});Common Starlight OG pitfalls
- site config required: Set
siteinastro.config.mjs— without it, og:url and og:image absolute URLs won't generate correctly - Social image path: Images in
public/are served from root; reference them as absolute URLs including the domain - Head frontmatter overwrites: Frontmatter
headis merged with global head — duplicate tags may appear
Preview your Starlight OG tags
After deploying, paste any docs URL into OGFixer to verify how your social previews look on Twitter, LinkedIn, Discord, and Slack.
Check your OG tags free →