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,.otfor.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
pageandsite. <name>.size- Required
- The text’s size in pixels, from 1 to 630: a fixed size such as
36, orup to 75for Statac to fit it. <name>.colour- Required
#RGBor#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 intemplates/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 asfonts/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/ 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_imageandcard, beside every other field - Images: where Statac finds an image, and its alt text
- Templates: what a layout can show, and what
headlinecalls a page
Something unclear or wrong? Open an issue.