Open Graph is a protocol created by Facebook. It allows pages on your site to be richly embedded into other sites and applications.
You've probably seen this in action when posting a link on Facebook, Twitter, Slack, iMessage, or Discord. Links posted in supported applications will display the Open Graph metadata which often includes an image. This library will generate those images for you.
[!WARNING] This integration has only been tested with statically rendered sites. It is untested with server-side rendering.
To better illustrate these steps, I've created a video following them to help others follow along.
Add this integration to your Astro config:
Option 1: use the astro
command:
npx astro add astro-opengraph-images
Option 2: install the package and add the integration to your Astro config:
npm i astro-opengraph-images
+import opengraphImages from "astro-opengraph-images";
export default defineConfig({
integrations: [
+ opengraphImages()
],
});
Install React. React is used by the presets, and can be used to easily author custom images. Note that React is only used for generating the images and will not be shipped to clients.
npm i -D react
Install the fonts you want to use. Fonts must be explicitly declared to be used for images. System fonts are not available. For this quick start guide, we'll install the Roboto font:
npm i @fontsource/roboto
You can find more fonts on Fontsource, or you can use any font file that you have. See Satori's font documentation for more information.
Configure the integration in your Astro config:
-import opengraphImages from "astro-opengraph-images";
+import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
- opengraphImages()
+ opengraphImages({
+ options: {
+ fonts: [
+ {
+ name: "Roboto",
+ weight: 400,
+ style: "normal",
+ data: fs.readFileSync("node_modules/@fontsource/roboto/files/roboto-latin-400-normal.woff"),
+ },
+ ],
+ },
+ render: presets.blackAndWhite,
+ }),
],
});
Set the site
property in your Astro config:
Open Graph requires URLs to be absolute, including the domain your site is hosted at. This integration uses the site defined in your Astro config to create the correct URLs for Open Graph which is site
must be defined.
export default defineConfig({
+ site: "https://<your site>.com",
integrations: [
opengraphImages({
options: {
fonts: [
{
name: "Roboto",
weight: 400,
style: "normal",
data: fs.readFileSync("node_modules/@fontsource/roboto/files/roboto-latin-400-normal.woff"),
},
],
},
render: presets.blackAndWhite,
}),
],
});
Update your main Astro layout with the appropriate meta
tags. The Open Graph site has more information possible tags.
The following meta
tags must be defined:
og:title
og:type
og:image
getImagePath
(example shown below).og:image
does not match what this integration expects then your site will fail to build. This will ensure your site is correctly configured to display Open Graph images.og:description
Your site will fail to build if the tags above are not set.
Option 1: Use the astro-seo
package:
Install the astro-seo
package:
npm i astro-seo
Update your Astro layout to use the SEO
component:
---
+import { SEO } from "astro-seo";
+import { getImagePath } from "astro-opengraph-images";
interface Props {
title: string;
}
const { title } = Astro.props;
+const { url, site } = Astro;
+const openGraphImageUrl = getImagePath({ url, site });
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="https://github.com/shepherdjerred/astro-opengraph-images/blob/main/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
+ <SEO
+ openGraph={
+ {
+ basic: {
+ title: title,
+ type: "website",
+ image: openGraphImageUrl,
+ url: url,
+ },
+ optional: {
+ description: "My page description",
+ },
+ }
+ }
+ />
</head>
<body>
<slot />
</body>
</html>
Option 2: Manually add the meta
tags to your Astro layout.
Build your site. You should see a .png
file next to each .html
page in your dist
folder. Double-check that the og:image
proprety in your .html
file matches the path to the .png
file.
Deploy your site. You can verify that your images are correct by:
There is an example site using this integration under examples/
.
If you're using this project, open a PR to add your site to this list.
You can create your own custom images with a render function. Take a look at how a preset works.
Renderers have access to the page's DOM using jsdom. You can use this to render your Open Graph image using any of the content from the associated HTML page. An example of this is shown in the custom property preset which shows a preview of the page's body text in the Open Graph image.
This library uses Satori to convert React components to SVG. The SVG is then converted to a PNG using resvg-js.
[!TIP] Satori supports a subset of CSS. Be sure to familiarize yourself with its limitations.
You can use the Satori playground to work on your images.
You can use Tailwind syntax with tw-to-css. An example is the Tailwind preset. You'll need to install this package yourself.
Presets are located in src/presets/
. Open a pull request to contribute a preset you've created.
Note: some presets use the tw-to-css
library. You'll need to install this dependency separately when using one of these presets. You'll see an error if the library is not already installed.
npm i tw-to-css
backgroundImage
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.backgroundImage,
}),
],
});
blackAndWhite
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.blackAndWhite,
}),
],
});
brandedLogo
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.brandedLogo,
}),
],
});
customProperty
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.customProperty,
}),
],
});
gradients
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.gradients,
}),
],
});
podcast
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.podcast,
}),
],
});
rauchg
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.rauchg,
}),
],
});
simpleBlog
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.simpleBlog,
}),
],
});
tailwind
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.tailwind,
}),
],
});
vercel
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.vercel,
}),
],
});
waveSvg
import opengraphImages, { presets } from "astro-opengraph-images";
export default defineConfig({
integrations: [
opengraphImages({
+ render: presets.waveSvg,
}),
],
});
Here are some similar libraries using Satori and Astro. I haven't done a feature comparison.