Getting Started
OpenGraph images are created by taking a snapshot of a webpage hosted on your own webserver. If you dont have a webserver readily available, you can create a project site from scratch in Github Pages and use the template for your index.html
.
You can use the template below as a base for creating your own templates. This template sets up a canvas that will support the default 1200x600
or 1200x630
sizes and uses tailwindcss and alpinejs. The rendering process will automatically set the canvas size so you do not need to include the canvas element in your templates.
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/alpinejs" defer></script>
</head>
<body class="h-screen">
<div class="flex items-center h-full bg-neutral-800">
<div class="relative w-full h-full mx-auto overflow-hidden bg-white" x-data="openGraphImage();">
<!-- Start: Your HTML Template -->
<h1 class="flex items-center justify-center h-full text-3xl">
<span x-text="params.title || 'Use the `title` query parameter to change me.'"></span>
</h1>
<!-- End: Your HTML Template -->
</div>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('openGraphImage', () => {
const params = new URLSearchParams(window.location.search);
return {
params: Object.fromEntries(params.entries()),
init() {
window.__og = window.__og || [];
// Set the default destination for `link.opengraphimage.com`
window.__og.push(['link', 'https://www.mywebsite.com']);
// Give alpine.js a chance to finish before triggering the render
this.$nextTick(() => {
window.__og.push(['ready']);
});
},
};
});
});
</script>
</body>
</html>
If you went the GitHub pages route, you should have a URL that looks something like this:
Even if you have your own webserver you still have a URL that is comprosed of these parts:
Setting Up your Origin
The HOST
is what you will use for the “Render Base URL” when creating your origin. The “Render Base URL” can also include a base path to help you organize your templates. This is especially handy when you need to create a default image for a template that has a different render size.
Building Your URL
Your origin KEY
is combined with the PATH
and QUERY STRING
to create the path for your image. The DOMAIN
part of the url can be cdn.opengraphimage.com
, to render an image, or link.opengraphimage.com
for redirecting the user to the link
specified using the javascript api.
You can also use the shorter cdn.ogimg.co
and link.ogimg.co
domains.
During the render process, the PATH
and QUERY STRING
are passed to the “Render Base URL” server, along with any default render params behind the scenes.
While this URL will work, it will only return the default image you created when setting up the origin. We serve the default image whenever we encounter an error from your host, rendering, or if we get a missing or invalid signature.
Securing Your Renders
To complete your URL, you will need to generate the signature using the origin SECRET
and KEY
combined with the PATH
and QUERY STRING
. Signed URLs should only be generated on a server or at build time.
Once you have the MD5 hash signature, you will append it to the end of the querystring as an s
parameter.
Here are some other things to look out for when building your URL:
- All querystring keys and values must also be percent encoded before signing.
-
Ensure the path you are signing starts with your origin
key
and not a/
Once you have the signed URL, you can use it for your og:image
meta tags or image src
as described in the documentation.
Example Code For Generating An MD5 Signature
Node.js
const crypto = require('crypto');
const getOGImageUrl = (basePath, key = 'key', secret = 'secret') => {
const path = `${key}${basePath}`;
const signature = crypto.createHash('md5').update(`${secret}${path}`).digest('hex').toString();
if (path.indexOf('?') === -1) {
return `https://cdn.opengraphimage.com/${path}&s=${signature}`;
}
return `https://cdn.opengraphimage.com/${path}?s=${signature}`;
}
console.log(`<meta property="og:image" content="${getOGImageUrl('/my-page-url/')}">`);
Elixir
defmodule OpenGraphImage do
def get_og_image_url(base_path, key \\ "key", secret \\ "secret") do
path = "#{key}#{base_path}"
signature =
:crypto.hash(:md5, "#{secret}#{path}") |> Base.encode16(case: :lower)
if String.contains?(path, "?") do
"https://cdn.opengraphimage.com/#{path}&s=#{signature}"
else
"https://cdn.opengraphimage.com/#{path}?s=#{signature}"
end
end
end
IO.puts ~s(<meta property="og:image" content="#{OpenGraphImage.get_og_image_url("/my-page-url/")}">)
PHP
<?php
function getOGImageUrl($basePath, $key = 'key', $secret = 'secret') {
$path = $key . $basePath;
$signature = md5($secret . $path);
if (strpos($path, '?') === false) {
return "https://cdn.opengraphimage.com/" . $path . "&s=" . $signature;
}
return "https://cdn.opengraphimage.com/" . $path . "?s=" . $signature;
}
echo '<meta property="og:image" content="' . getOGImageUrl('/my-page-url/') . '">';
?>