Menu
og-imagescustom-templatestutorial

Design Custom OG Image Templates with HTML & CSS

SnapSharp Team·March 24, 2026·4 min read

The 5 built-in templates cover common cases — blog posts, social cards, product cards. But what if you need your brand colors, your logo, your layout?

Custom templates let you design OG images with full HTML/CSS control, then generate them via the same API.

How it works

  1. Write an HTML template with {{variable}} placeholders
  2. Save it in the dashboard editor (or via API)
  3. Call POST /v1/og-image with your template slug and data
  4. Get back a pixel-perfect image

Step 1: Design your template

Start with this skeleton:

<div style="
  width: 1200px;
  height: 630px;
  background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 60px;
  font-family: system-ui, -apple-system, sans-serif;
  color: white;
">
  <div>
    <div style="
      font-size: 14px;
      text-transform: uppercase;
      letter-spacing: 2px;
      color: #10b981;
      margin-bottom: 20px;
    ">{{tag}}</div>
    <h1 style="
      font-size: 52px;
      font-weight: 700;
      line-height: 1.2;
      margin: 0;
    ">{{title}}</h1>
  </div>
  <div style="
    display: flex;
    align-items: center;
    gap: 16px;
  ">
    <div style="
      width: 48px;
      height: 48px;
      border-radius: 50%;
      background: #10b981;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 20px;
      font-weight: 600;
    ">{{author_initial}}</div>
    <div>
      <div style="font-size: 18px; font-weight: 500;">{{author}}</div>
      <div style="font-size: 14px; color: #94a3b8;">{{date}}</div>
    </div>
  </div>
</div>

Step 2: Save in the editor

Go to Dashboard → Templates → Create Template. Paste your HTML, give it a name (e.g. "branded-blog"), and save. The editor shows a live preview as you type.

Step 3: Generate images

curl -X POST "https://api.snapsharp.dev/v1/og-image" \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "template": "branded-blog",
    "data": {
      "title": "We Just Raised Our Series A",
      "author": "Sarah Chen",
      "author_initial": "S",
      "date": "March 24, 2026",
      "tag": "Company News"
    }
  }' -o og.png

Or with the SDK:

const image = await snap.ogImage('branded-blog', {
  title: 'We Just Raised Our Series A',
  author: 'Sarah Chen',
  author_initial: 'S',
  date: 'March 24, 2026',
  tag: 'Company News',
});

Design tips

Dimensions: Always use width: 1200px; height: 630px on your root element. This is the standard OG image size that works on all platforms.

Fonts: Use system fonts. External font files won't load. system-ui, -apple-system, 'Segoe UI', sans-serif renders consistently.

Text size: OG images display at ~500px on most social platforms. Use minimum 40px for titles, 18px for body text.

Colors: Dark backgrounds with light text tend to pop in social feeds. Avoid pure white backgrounds — they blend in with the platform UI.

Testing: Use the OG Preview tool to see how your images look on Twitter, LinkedIn, and Facebook.

Built-in vs custom

Built-inCustom
Plan requiredStarter+Growth+
EditableNoFull HTML/CSS control
Templates available5Unlimited
Brand customizationbg_color onlyEverything

Availability

Custom templates require a Growth plan or above ($49/mo). Built-in templates are available on Starter+ ($19/mo).

Full documentation: snapsharp.dev/docs/custom-templates

Frequently Asked Questions

Can I use web fonts (Google Fonts, custom TTF) in my OG template?

Not reliably. External stylesheets and font files aren't guaranteed to load within the render timeout. Stick to system fonts (system-ui, -apple-system, Segoe UI, sans-serif) which render consistently across our Chromium pool. If you need brand fonts, ask support about including your TTF in the template — this is available on Business+ plans.

How do I use conditional rendering in a template?

Templates use Handlebars syntax. Wrap optional sections in {{#if variable}}...{{/if}}. For example: {{#if tag}}<span class="tag">{{tag}}</span>{{/if}} only renders the tag span when tag is truthy in your data payload.

Can I include images (logo, avatar) in a custom OG template?

Yes — reference them by absolute URL: <img src="https://your-site.com/logo.svg" />. The renderer waits for images to load before capturing. For best performance, host images on a CDN with aggressive cache headers, and prefer SVG/PNG over formats that require extra decoding.

What's the max template size and render time?

Templates render at 1200×630 by default (override via width and height in the request body). Render time is typically 300–800 ms for static templates, +200–400 ms if external images load. Templates exceeding 5 MB of HTML or 30 seconds of render time will fail.

How do I version a template without breaking existing generated images?

Create a new template (e.g. branded-blog-v2) rather than editing branded-blog. Switch your API calls to the new slug gradually. SnapSharp's cache is keyed by template + data, so old cached images remain valid under the old slug until their TTL expires.

Can I test a template locally before saving it in the dashboard?

Yes — paste the HTML into a browser with the root element sized 1200×630 and replace {{variables}} with static test data. What you see in Chrome is within a few pixels of what the API produces. For full fidelity, use the live preview in the dashboard editor.


Related: Custom Templates docs · Pricing · Generate OG Images in Next.js

Design Custom OG Image Templates with HTML & CSS — SnapSharp Blog