We can't find the internet
Attempting to reconnect
The rendering platform turns any webpage into a dynamic image. Point an origin at HTML you host, pass parameters through the URL, and get back a screenshot — at any size, for any use case. OG images, email banners, social cards, dashboard exports, publishing graphics — if you can build it in HTML, the platform can render it.
Looking for the quick path? If you just want OG images for link previews, skip the platform setup and use an OG Image Template instead — no hosting required.
You can use the template below as a starting point. It sets up a canvas using Tailwind CSS and Alpine.js. The rendering process sets the canvas size automatically, so the container element is optional.
<!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="overflow-hidden relative mx-auto w-full h-full bg-white" x-data="openGraphImage();">
<!-- Start: Your HTML Template -->
<h1 class="flex justify-center items-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
keyand 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/') . '">';
?>