Statac

Social cards

What a link preview shows of a page, and the social card Statac draws for it.

A social card is an image Statac can draw for each page, with text from the page such as its title.

What a link preview shows

When someone pastes a link into another site or app, that site or app builds a preview from the <meta> tags in the page’s <head>. Statac doesn’t write these tags. A layout writes them, like this:

{% set description = page.summary | default(page.opening) | default("") %}
<meta property="og:title" content="{{ page.og_title }}">
<meta property="og:type" content="{{ "article" if page.date else "website" }}">
<meta property="og:site_name" content="{{ site.title }}">
<meta property="og:locale" content="{{ page.language | replace("-", "_") }}">
{% if description %}
<meta property="og:description" content="{{ description }}">
{% endif %}
{% if site.url is defined %}
<meta property="og:url" content="{{ page.url | absolute }}">
{% endif %}
Tag What it holds
og:title The page’s title for link previews: page.og_title.
og:description The page’s summary, or else the text of its first paragraph. The layout leaves it out if the page has neither.
og:url The page’s full URL. The layout leaves it out if the site has no url.
og:site_name The site’s title.
og:type article for a page with a date, website for any other page.
og:locale The page’s language, with an underscore: en-GB becomes en_GB.
og:image, with its size and alt The page’s social card, or its social image. The card’s lines in the layout write these tags, and only on a page that has one.

page.og_title is the page’s og_title, or else the title that headline(page) returns. If a title is too long for a card, give the page a shorter one in its front matter:

title: A title with more words in it than a card has room to draw
og_title: A shorter title

Turn cards on

A card needs settings and files, and you supply both: Statac comes with no background and no font.

Where What
templates/og.yaml The card’s settings: its background, its fonts, and the texts to draw.
templates/og/ The background, an image 1,200 pixels wide and 630 tall, and at least one font file.

This templates/og.yaml draws one text, the page’s title, over background.png in the font text.ttf:

background: background.png
font: text.ttf

title.text: "{{ page.og_title }}"
title.place: centre
title.size: up to 75
title.colour: "#ffffff"

From the next build on, Statac draws a card for every page whose layout reads page.card, if the site has a url.

To turn cards off, remove templates/og.yaml.

Put the card in a layout

Add these lines to the layout’s <head>:

{% if page.card is defined %}
<meta property="og:image" content="{{ page.card.url | absolute }}">
{% if page.card.width %}
<meta property="og:image:width" content="{{ page.card.width }}">
<meta property="og:image:height" content="{{ page.card.height }}">
{% endif %}
<meta property="og:image:alt" content="{{ page.card.alt }}">
<meta name="twitter:card" content="summary_large_image">
{% endif %}

Statac draws a card only for a page whose layout reads page.card. A page without a card has no page.card, so the first line checks for it.

A social card in the Reference gives each of page.card’s names: its url, its width and height, 1200 and 630 for a card Statac drew, and its alt, the words drawn on it or a social image’s own alt text.

The absolute filter puts the site’s url in front of the card’s URL, because a link preview needs the full URL. You can read page.card in a layout, or in a snippet that a layout calls.

The card’s settings

In templates/og.yaml:

background: background.png
font: [text.ttf, more.ttf]
padding: 70

title.text: "{{ page.og_title }}"
title.place: centre
title.size: up to 75
title.colour: "#F2E9D3"

footer.text: "{{ site.title }}"
footer.place: bottom
footer.size: 36
footer.colour: "{{ page.accent | default('#B9A88F') }}"
background
Required
The image Statac draws under everything, in templates/og/: a JPEG, a PNG or a WebP that isn’t animated, 1,200 pixels wide and 630 tall.
font
Required
A font file in templates/og/, ending .ttf, .otf or .ttc, or a list of them, which Statac tries in order.
padding
Default 60
The distance in pixels between each edge of the card and the texts, from 0 to 314.
<name>.text
Required
The words to draw, written as a template that can read page and site.
<name>.place
Required
Where the text goes: one of nine places.
<name>.size
Required
The text’s size in pixels, from 1 to 630: a fixed size such as 36, or up to 75 for Statac to fit it.
<name>.colour
Required
#RGB or #RRGGBB, or a template that produces one.
<name>.font
Default The card’s font
The fonts Statac draws this text in, written the same way as font: a file in templates/og/, or a list of them, which Statac tries in order.

Every other line belongs to a text that you name, such as title or footer. Each text needs its text, place, size and colour; its font is optional. Statac draws the texts in the order you write them.

  • A colour starting # goes in quotes, or YAML reads it as a comment.
  • Files go in templates/og/, or in a folder inside it if you like, such as fonts/text.ttf.

For each page, Statac builds each text the same way as a template, with page set to the page the card is for. If some pages have no value for a text or a colour, give it a default: {{ page.summary | default("") }}. Statac draws the result as plain text, and never reads it as markup.

Where texts go, and how large

Left Middle Right
Top top left top top right
Middle left centre right
Bottom bottom left bottom bottom right

Statac stacks the texts that share a place in the order you write them, with a gap of half the lower text’s line height between each text and the next. Each text wraps to fit the width inside the padding, and each of its lines is 1.2 times the text’s size tall. Statac aligns a text left in a left place, right in a right place, and centres it in the others. If a text comes out empty, such as an empty summary, it takes up no space.

The top row starts at the top edge of the padding, and the bottom row ends at its bottom edge. Statac centres the middle row’s texts in the height left between the two.

Statac fits up to sizes only in the middle row. There, it finds the largest size, down to 45, at which the whole row fits, and draws each text sized up to at that size or at its own up to size, whichever is smaller. It draws a fixed size, or an up to size below 45, at the size given. In the top and bottom rows Statac fits nothing, and draws an up to size at the size given.

Fonts

For each character, Statac tries the fonts in font in the order you write them, so a second font can supply characters the first one lacks, such as those of another script.

To draw emoji, put an emoji font last in the list. Noto Emoji, for example, draws them in the text’s colour. Statac has no built-in font.

A text can have fonts of its own, such as a display font for the title and the card’s text font for the rest:

font: [text.ttf, NotoEmoji.ttf]
title.font: [display.otf, text.ttf, NotoEmoji.ttf]

Statac draws a text that has its own fonts only in those, trying them in order, so its list needs the fallbacks too. The first font in the text’s own list sets where its lines sit. The card still needs its font.

Other cards

templates/og.<name>.yaml sets up another card, called <name>, the same way, with its files also in templates/og/. For example, og.wide.yaml sets up the card called wide. To use it on a page, add this to the page’s front matter:

card: wide

To use that card on every page in a folder, put pages.card: wide in the folder’s index.md, which cascades it as it cascades any field. A page that doesn’t name a card gets the site’s main card, templates/og.yaml.

A social image in place of a card

In a page’s front matter:

og_image: cover.jpg

Link previews then show this image in place of a card, even if the page also names a card. Statac finds the image the same way as an image in a page’s content, and publishes the original file, unchanged.

page.card then holds the image’s URL, its size if the file records one, and as alt the alt text in cover.jpg.yaml beside the image, or else page.og_title.

What a card needs

A page needs Because
The card’s settings: templates/og.yaml, or the og.<name>.yaml the page picks They say what to draw.
The site’s URL, url in statac.yaml A link preview needs the card’s full URL.
A layout that reads page.card Reading page.card is what asks Statac for the card.
To be published at its own URL A page that redirects has no card, and nor does a list page with index_page: false.
note  No site URL: Statac leaves out social cards until the site has a `url`
  templates/og.yaml, line 1
   1 │ background: background.png
     │ ^^^^^^^^^^^^^^^^^^^^^^^^^^
  Add the site's full URL to `statac.yaml`, such as `url: https://example.org/`.
  More: https://statac.dev/e/no-site-url/

Without a url, Statac draws no cards, and page.card has no value on any page. A build with --url draws the cards for the URL you give it.

Statac draws a draft’s card whenever it builds the draft: in serve’s preview, and with statac build --drafts.

When Statac doesn’t draw a card

Problem When Then
Unusable card file A background that isn’t 1,200 by 630, or isn’t a JPEG, a PNG or a WebP that isn’t animated; a font file that Statac can’t read as a font. The build stops.
Unreadable image A background that is cut short or damaged. The build stops.
Card not drawn A text doesn’t fit, or contains a character that none of its fonts has. That page gets no card, but Statac still builds it.
Unused card No layout reads page.card, or no page picks the card called <name>. Statac draws nothing for it.

What Statac keeps between builds

Drew 16 cards.

Statac keeps each card it draws in .statac/, and draws it again only when its text, its settings or its files change. build prints how many cards it drew.

After a build that publishes the site, Statac removes from .statac/ each card that no page uses any more. A build with --url adds cards but never removes any.

statac check doesn’t draw any cards, but it builds each card’s texts and works out where they go, so it finds the problems above.

Where next?

  • Front matter: og_title, og_image and card, beside every other field
  • Images: where Statac finds an image, and its alt text
  • Templates: what a layout can show, and what headline calls a page

Something unclear or wrong? Open an issue.