GitHub Pages Open Graph Tags: How to Add OG Meta to Static Sites
Add og:title, og:image, og:description, and Twitter card tags to GitHub Pages sites — covering Jekyll, plain HTML, and custom domain setups.
GitHub Pages and OG tags
GitHub Pages hosts static HTML files, which is ideal for OG tags — social crawlers receive pre-built HTML with no JavaScript execution required. The challenge is that GitHub Pages has no server-side logic, so you need to embed OG tags directly in each HTML file (or use a static site generator like Jekyll to do it automatically).
Option 1: Plain HTML — add tags manually
For a simple static site, add OG tags directly inside the <head> of each HTML file:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My GitHub Pages Site</title> <!-- Open Graph --> <meta property="og:title" content="My GitHub Pages Site" /> <meta property="og:description" content="A description of my site." /> <meta property="og:image" content="https://username.github.io/repo/og.jpg" /> <meta property="og:url" content="https://username.github.io/repo/" /> <meta property="og:type" content="website" /> <!-- Twitter Card --> <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:title" content="My GitHub Pages Site" /> <meta name="twitter:description" content="A description of my site." /> <meta name="twitter:image" content="https://username.github.io/repo/og.jpg" /> </head> <body>...</body> </html>
Place your OG image in the repo root or an assets/ folder. Reference it with an absolute URL using your GitHub Pages domain.
Option 2: Jekyll (built-in to GitHub Pages)
GitHub Pages natively supports Jekyll. Create a _includes/head.html that generates OG tags from page front matter:
{# _includes/head.html #}
{% assign og_title = page.title | default: site.title %}
{% assign og_desc = page.description | default: site.description %}
{% assign og_image = page.image | default: '/assets/og-default.jpg' | absolute_url %}
{% assign og_url = page.url | absolute_url %}
<meta property="og:title" content="{{ og_title | escape }}" />
<meta property="og:description" content="{{ og_desc | escape }}" />
<meta property="og:image" content="{{ og_image }}" />
<meta property="og:url" content="{{ og_url }}" />
<meta property="og:type" content="{{ page.layout | default: 'website' }}" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{{ og_title | escape }}" />
<meta name="twitter:description" content="{{ og_desc | escape }}" />
<meta name="twitter:image" content="{{ og_image }}" />In your _config.yml, set your site URL:
# _config.yml url: "https://username.github.io" baseurl: "/my-repo" title: "My Site" description: "My site description."
Then add per-page metadata in front matter:
--- title: "My Blog Post" description: "Post description for OG tags." image: /assets/posts/my-post-og.jpg ---
Custom domain setup
If you use a custom domain with GitHub Pages, update all OG image URLs to use your custom domain. Your GitHub Pages URL (username.github.io/repo) still works, but the custom domain is canonical. Set it in _config.yml:
# _config.yml with custom domain url: "https://yourdomain.com" baseurl: ""
Common GitHub Pages OG mistakes
- Wrong base URL: GitHub Pages sites at
username.github.io/repo-nameneed the correctbaseurlset in_config.yml. - Relative image paths: always use absolute URLs for og:image. Use Jekyll's
| absolute_urlfilter. - Missing HTTPS: GitHub Pages serves over HTTPS by default. Ensure all asset URLs also use HTTPS.
Preview your OG tags free at OGFixer.com → Paste your GitHub Pages URL to verify how your link card looks on Twitter, LinkedIn, Discord, and Slack.