If your site is behind Cloudflare, you can use a Worker to add a SnapOG og:image tag to every page — without touching your origin server.
How it works
- A visitor (or social crawler) requests a page through Cloudflare.
- The Worker fetches the page from your origin.
- Cloudflare's
HTMLRewriterstreams through the HTML, adding or replacing theog:imagemeta tag to point atsnapog.com/s/<your-page-url>. - The modified response is returned to the visitor.
Unlike regex-based rewriting, HTMLRewriter is a streaming HTML parser — it doesn't buffer the entire page in memory, so it's fast even on large pages.
Setup
1. Create a Worker
If you haven't already, install Wrangler and scaffold a new project:
shell
npm create cloudflare@latest snapog-og-image
Replace the generated worker code with one of the scripts below.
Every page gets a SnapOG card, even if the origin already sets one.
Pages that already have an og:image keep theirs. SnapOG only fills in the gaps.
javascript
export default {
async fetch(request) {
const response = await fetch(request);
const contentType = response.headers.get("content-type") || "";
if (!contentType.includes("text/html")) {
return response;
}
const pageUrl = encodeURIComponent(request.url);
const ogImage = `<meta property="og:image" content="https://snapog.com/s/${pageUrl}" />`;
let hasOgImage = false;
return new HTMLRewriter()
.on('meta[property="og:image"]', {
element(el) {
hasOgImage = true;
el.replace(ogImage, { html: true });
}
})
.on("head", {
element(el) {
el.onEndTag((end) => {
if (!hasOgImage) {
end.before(ogImage, { html: true });
}
});
}
})
.transform(response);
}
};
javascript
export default {
async fetch(request) {
const response = await fetch(request);
const contentType = response.headers.get("content-type") || "";
if (!contentType.includes("text/html")) {
return response;
}
const pageUrl = encodeURIComponent(request.url);
const ogImage = `<meta property="og:image" content="https://snapog.com/s/${pageUrl}" />`;
let hasOgImage = false;
return new HTMLRewriter()
.on('meta[property="og:image"]', {
element() { hasOgImage = true; }
})
.on("head", {
element(el) {
// onEndTag fires after all children have been processed,
// so hasOgImage is set by then if the tag exists
el.onEndTag((end) => {
if (!hasOgImage) {
end.before(ogImage, { html: true });
}
});
}
})
.transform(response);
}
};
2. Configure the route
In your wrangler.toml, set up a route so the Worker runs on your domain:
toml
name = "snapog-og-image"
main = "src/index.js"
compatibility_date = "2024-01-01"
routes = [
{ pattern = "yoursite.com/*", zone_name = "yoursite.com" }
]
The pattern controls which URLs the Worker handles. Some examples:
yoursite.com/*— all pagesyoursite.com/blog/*— only blog pages*.yoursite.com/*— all subdomains
You can also configure routes in the Cloudflare dashboard under Workers Routes if you prefer not to use Wrangler.
3. Deploy
What the script does
- Fetches the page from your origin with
fetch(request)— Cloudflare handles this as a normal proxy request. - Non-HTML responses pass straight through with no modification.
- For HTML responses,
HTMLRewriterstreams through the document looking for<meta property="og:image">tags and the</head>closing tag. - Depending on the mode, it either replaces the existing tag or injects one if none was found.
Verifying it works
After deploying, check any page on your site:
shell
curl -s https://yoursite.com/some-page | grep og:image
You should see something like:
html
<meta property="og:image" content="https://snapog.com/s/https%3A%2F%2Fyoursite.com%2Fsome-page" />
If you still see the old tag, you may need to purge the Cloudflare cache for that URL.
You can also paste the URL into the Facebook Sharing Debugger or Twitter Card Validator to see the card that social platforms will display.
Caching
SnapOG caches rendered images for about a week. If you need to force a refresh after updating a page, see the cache refresh docs.