Multiple Domains & Environments
One account across every domain, subdomain, and environment
For a single site, the connection tag is the right tool: one paste, no keys. Reach for this when one site isn’t the whole picture:
- Multiple environments: staging and production under one account.
- Subdomains: a product where each account or page is its own subdomain under one apex.
- Separate sites: several properties you run, kept on one account, one bill, one dashboard.
Available on the Business plan.
How it works
Instead of a connection tag per host, your app signs the OpenGraph+ image URL for the page being shared and outputs it as the og:image tag. The signature carries your public key and an HMAC of the request, so OpenGraph+ knows the request is yours and renders that exact page. Renders from every domain and subdomain roll up to one site under your account.
Signing happens on each request, so this is for server-rendered apps. A static site generator can’t sign per request; for those, use a connection tag per site.
Rails
Install the opengraphplus gem, set your API key, and include the controller concern. It signs request.url for you, so every domain and subdomain emits the right tag with no per-host setup:
# Gemfile
gem "opengraphplus"
# config/initializers/opengraphplus.rb
OpenGraphPlus.configure do |ogplus|
ogplus.api_key = ENV["OGPLUS_API_KEY"]
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include OpenGraphPlus::Rails::Controller
end
Render the tags in your layout <head>:
<%= open_graph_meta_tags %>
Other frameworks
The signed URL has three parts: your public key, an HMAC-SHA256 of the request path signed with your secret key (truncated to 16 bytes), and the page URL. Both come from your dashboard’s API Keys page. Build the query string once and use it in both the signature input and the final URL, so the encoding always matches.
The URL format:
https://opengraphplus.com/api/websites/v1/{signature}/image?url={page-url}
where signature = base64url(public_key + ":" + hmac_sha256(secret_key, "/image?" + query)[0..15]).
Node.js
import crypto from "node:crypto";
function ogplusImage(pageUrl, { publicKey, secretKey }) {
const query = new URLSearchParams({ url: pageUrl }).toString();
const hmac = crypto.createHmac("sha256", secretKey).update(`/image?${query}`).digest();
const payload = Buffer.concat([Buffer.from(`${publicKey}:`), hmac.subarray(0, 16)]);
const signature = payload.toString("base64url");
return `https://opengraphplus.com/api/websites/v1/${signature}/image?${query}`;
}
PHP
function ogplus_image(string $pageUrl, string $publicKey, string $secretKey): string {
$query = http_build_query(['url' => $pageUrl]);
$hmac = substr(hash_hmac('sha256', "/image?{$query}", $secretKey, true), 0, 16);
$signature = rtrim(strtr(base64_encode("{$publicKey}:{$hmac}"), '+/', '-_'), '=');
return "https://opengraphplus.com/api/websites/v1/{$signature}/image?{$query}";
}
Python
import base64, hashlib, hmac
from urllib.parse import urlencode
def ogplus_image(page_url, public_key, secret_key):
query = urlencode({"url": page_url})
digest = hmac.new(secret_key.encode(), f"/image?{query}".encode(), hashlib.sha256).digest()[:16]
payload = f"{public_key}:".encode() + digest
signature = base64.urlsafe_b64encode(payload).rstrip(b"=").decode()
return f"https://opengraphplus.com/api/websites/v1/{signature}/image?{query}"
Output the result as your og:image, and add twitter:card so platforms render the large card:
<meta property="og:image" content="{ ogplus_image(current_page_url) }">
<meta name="twitter:card" content="summary_large_image">