← Docs

Template Authoring Guide

How to build ShareMagic OG image templates using Liquid and the available page variables.

ShareMagic templates are HTML documents rendered with Liquid. When someone shares a link, ShareMagic fetches the page, extracts metadata (OG tags, JSON-LD, <title>, etc.), and injects it into your template as Liquid variables. The rendered HTML is then screenshotted at 1200x630 to produce the OG image.

Quick Start

Here’s a minimal template that works on any site:

<div style="width: 1200px; height: 630px; display: flex; align-items: center; justify-content: center; background: #18181b; color: white; font-family: system-ui; padding: 80px;">
  <div>
    <h1 style="font-size: 48px; margin: 0;">{{ title }}</h1>
    <p style="font-size: 24px; color: #a1a1aa; margin-top: 16px;">{{ description }}</p>
    <p style="font-size: 18px; color: #71717a; margin-top: 24px;">{{ domain }}</p>
  </div>
</div>

This pulls the page title, meta description, and domain name — the three variables available on every page.

Canvas Size

Templates render at 1200x630 pixels (the standard OG image ratio of 1.91:1). Your root element should be exactly this size. You can use inline styles, <style> blocks, or external stylesheets and Google Fonts — they’re all supported.

<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  .card { width: 1200px; height: 630px; }
</style>
<div class="card">
<!-- your layout -->

</div>

Variables

Variables are extracted from the shared page’s metadata and injected into your template. They resolve in priority order: JSON-LD first, then OG meta tags, then standard HTML tags.

Core Variables (Available on Every Page)

Variable Source Priority Description
title og:title > <title> The page title
description og:description > <meta name="description"> The page description
image og:image The page’s existing OG image URL (useful as a background or fallback)
domain Extracted from URL The site’s domain name (e.g. example.com)
friendly_url Computed A clean version of the full URL without protocol

Use them with standard Liquid syntax:

<h1>{{ title }}</h1>
<p>{{ description }}</p>
<img src="{{ image }}" />
<span>{{ domain }}</span>

Meta Tag Variables

Access any meta tag directly using the meta prefix:

{{ meta.author }}
{{ meta.keywords }}
{{ meta.og:site_name }}
{{ meta.twitter:creator }}

This reads from the page’s <meta> tags. For example, meta.author resolves <meta name="author" content="...">.

JSON-LD Variables

If the page has JSON-LD structured data (using Schema.org types), you can access it by type and attribute:

<!-- Article schema (https://schema.org/Article) -->

{{ Article.headline }}
{{ Article.author.name }}
{{ Article.datePublished }}

<!-- Product schema (https://schema.org/Product) -->

{{ Product.name }}
{{ Product.brand.name }}
{{ Product.offers.price }}
{{ Product.offers.priceCurrency }}

<!-- Organization schema (https://schema.org/Organization) -->

{{ Organization.name }}
{{ Organization.logo }}

The variable name follows the pattern Type.attribute.nested_attribute. ShareMagic walks the JSON-LD graph to resolve values. See the full list of types and properties at schema.org/docs/schemas.html.

Checking If Variables Exist

Use Liquid conditionals to handle missing data gracefully:

{% if image %}
  <img src="{{ image }}" style="width: 100%; height: 100%; object-fit: cover;" />
{% else %}
  <div style="background: linear-gradient(135deg, #7c5cf2, #4f46e5); width: 100%; height: 100%;"></div>
{% endif %}

{% if Product.offers.price %}
  <span>{{ Product.offers | format_currency }}</span>
{% endif %}

Custom Filters

ShareMagic includes custom Liquid filters beyond the standard set:

format_currency

Formats a price from JSON-LD offers data into a localized currency string.

<!-- With a Product offers object -->

{{ Product.offers | format_currency }}
<!-- Output: "$29.99" -->

This reads price and priceCurrency from the Offer object automatically.

Template Patterns

Text-Only Card

Works on any page. Clean and reliable.

<div style="width: 1200px; height: 630px; display: flex; flex-direction: column; justify-content: space-between; background: #fff; padding: 80px; font-family: system-ui;">
  <div>
    <h1 style="font-size: 52px; color: #18181b; line-height: 1.1;">{{ title }}</h1>
    {% if description %}
      <p style="font-size: 24px; color: #71717a; margin-top: 20px; line-height: 1.4;">{{ description }}</p>
    {% endif %}
  </div>
  <p style="font-size: 18px; color: #a1a1aa;">{{ domain }}</p>
</div>

Image Background with Text Overlay

Uses the page’s existing OG image as a background.

<div style="width: 1200px; height: 630px; position: relative; font-family: system-ui;">
  {% if image %}
    <img src="{{ image }}" style="width: 100%; height: 100%; object-fit: cover;" />
    <div style="position: absolute; inset: 0; background: linear-gradient(to top, rgba(0,0,0,0.8) 0%, transparent 60%);"></div>
  {% else %}
    <div style="width: 100%; height: 100%; background: #18181b;"></div>
  {% endif %}
  <div style="position: absolute; bottom: 60px; left: 60px; right: 60px; color: white;">
    <h1 style="font-size: 48px; line-height: 1.1;">{{ title }}</h1>
    <p style="font-size: 20px; opacity: 0.7; margin-top: 12px;">{{ domain }}</p>
  </div>
</div>

Product Card (Requires Product JSON-LD)

Pulls structured product data for e-commerce pages.

<div style="width: 1200px; height: 630px; display: flex; background: #fff; font-family: system-ui;">
  {% if image %}
    <div style="width: 500px; height: 630px; flex-shrink: 0;">
      <img src="{{ image }}" style="width: 100%; height: 100%; object-fit: cover;" />
    </div>
  {% endif %}
  <div style="flex: 1; padding: 60px; display: flex; flex-direction: column; justify-content: center;">
    {% if Product.brand.name %}
      <p style="font-size: 16px; text-transform: uppercase; letter-spacing: 2px; color: #a1a1aa;">{{ Product.brand.name }}</p>
    {% endif %}
    <h1 style="font-size: 44px; color: #18181b; margin-top: 8px; line-height: 1.1;">{{ Product.name | default: title }}</h1>
    {% if Product.offers.price %}
      <p style="font-size: 36px; font-weight: 700; color: #18181b; margin-top: 24px;">{{ Product.offers | format_currency }}</p>
    {% endif %}
    <p style="font-size: 18px; color: #a1a1aa; margin-top: auto;">{{ domain }}</p>
  </div>
</div>

Testing Your Template

Use the Preview URL input on the template editor page to test against any live URL. ShareMagic will fetch the page, resolve variables, and render a preview.

You can also use the Inspector to see exactly what metadata a page exposes — this tells you which variables will be available in your template.

Tips

  • Always set a fixed canvas size. The root element must be 1200x630. If it’s not, the screenshot will be clipped or padded.
  • Inline styles, <style> blocks, external CSS, and Google Fonts all work. Use whatever’s easiest for your layout.
  • Handle missing variables. Not every page has JSON-LD or even a description. Use {% if variable %} checks to avoid blank spots.
  • {{ image }} pulls from og:image. If the page has its own OG image set (not a ShareMagic URL), you can use it as a background or fallback in your template.
  • Keep text large. OG images are often displayed at small sizes in feeds. Headlines should be 40px+ to stay readable when scaled down.
  • Test with multiple URLs. A template that looks great on your homepage might break on a blog post with a long title or missing description.