Social Cards and Structured Data

You fill in a title, a summary, some keywords and a feature image in the editor. This page is what Leed builds out of them — the exact tags that land in every page head, where each value comes from, and what happens when one is missing. Every tag described here is emitted on every plan.

The controls themselves live in the editor’s Page Settings panel; this page is the output side of that seam. Set it there, see it here.

What lands in every head, in order

Leed emits four metadata blocks, always in the same sequence:

  1. leed/metadata/siteMetadata — feed and sitemap discovery, the favicon, charset, generator, title, keywords, description, the canonical link, and a published meta.
  2. leed/metadata/twitterCard — the twitter:* properties.
  3. leed/metadata/ogCard — the og:* and article:* properties.
  4. The JSON-LD block — or, on almost every page, an HTML comment saying none was generated.

Note what is not in that list. Leed emits no <title> element. It emits <meta name="title">, which no browser tab and no search result uses. The <title> is your master template’s job — see How Templates Work.

Page metadata and the canonical URL

TagValueEmitted when
<meta charset>UTF-8always
<meta name="generator">Leed Eleventyalways
<meta name="title">the page titlealways
<meta name="keywords">the page’s keywordsonly when the page has keywords
<meta name="description">the page summary, falling back to the site descriptionalways (one or the other)
<link rel="canonical">canonicalUrl if a template sets one, otherwise the page’s own absolute URLalways except on /stubs/* pages, where it is suppressed entirely
<meta property="published">publishedAt, ISO-8601always
<link rel="icon">your favicononly when a favicon is set

The canonical URL is derived from where the page’s file sits, which means changing a slug changes the canonical URL. If the old address matters — and it does if anything links to it — add an alias so the old URL redirects rather than leaving it to 404.

Open Graph

PropertyValue sourceEmitted whenFallback
og:localesite localealways—
og:site_namesite titlealways—
og:sitesite URLalways—
og:titlethe page titlealwaysthe company Social Title (ogCard.title)
og:descriptionthe page summarywhen either existsthe company Social Description (ogCard.description)
og:imagethe page feature imagewhen an image resolvesogCard.image from site data
og:image:widthogCard.imageWidthwhenever og:image is emitted800
og:image:heightogCard.imageHeightwhenever og:image is emitted413
og:urlthe page’s absolute URLalways—
og:typearticle or websitealways—
article:published_timepublishedAt, ISO-8601og:type: article only—
article:modified_timemodifiedAt, ISO-8601og:type: article only—
article:publishersite titleog:type: article only—
article:authorone tag per visible author, carrying their full nameog:type: article only, and only when the page has authors—
article:tagthe page’s keywordsog:type: article only—

og:site is not a standard Open Graph property — og:site_name is, and is also emitted. It is harmless, and no consumer is known to read it; do not build anything on it.

Where the card image comes from

flowchart TD
  P["A page's head is rendered"] --> FI{"Does the page have<br/>a feature image?"}
  FI -- "yes" --> V["absoluteImageUrl(image, 'social')"]
  FI -- "no" --> OG{"Does site data set<br/>ogCard.image?"}
  OG -- "yes" --> V
  V --> BOTH["og:image AND twitter:image"]
  OG -- "no" --> T{"Which tag?"}
  T -- "Open Graph" --> N1["no og:image at all"]
  T -- "Twitter" --> L["the site logo,<br/>through the same transform"]

The two partials share the first two steps and part ways at the end: Open Graph stops, and emits no image tag at all, while the Twitter card falls back once more to your site logo. So a page with no feature image can unfurl with an image on X and without one on a platform that reads Open Graph.

The transform in the middle rewrites a CMS asset URL to its social Cloudflare Images variant, and makes the URL absolute if it is not already. That variant is why og:image:width and og:image:height default to 800 × 413 — those are the variant’s dimensions, and they describe Leed’s file, not yours. A site that supplies its own ogCard.image is not going through that variant at all, so it should state its own ogCard.imageWidth and ogCard.imageHeight alongside it or the two lines will describe someone else’s picture. The social variant is the same machinery behind image variants and responsive images.

Article versus website

og:type follows the Show In Feeds checkbox on the page type. With it on, the page is an article and gets the five article:* properties above; with it off, it is a website and gets none of them. It is the same switch that decides whether the page appears in your feeds and your AI files, and it cannot be split — a page cannot be an article while staying out of the feed.

Twitter / X cards

PropertyValue sourceEmitted whenFallback
twitter:cardogCard.cardType from site dataalwayssummary
twitter:urlthe page’s absolute URLalways—
twitter:sitethe company Twitter IDonly when one is set—
twitter:imagefeature image → ogCard.image → site logowhen any of the three resolves—
twitter:titlethe page titlealwaysthe company Social Title
twitter:descriptionthe page summaryonly when the page has a summarynone — the tag is omitted
twitter:creatora visible author’s own Twitter IDon feed-eligible pages, when the author has one—
twitter:label1 / twitter:data1the literal Est. reading time, and the page’s reading time in minutesonly when the page has a word count—

Two differences from Open Graph are easy to trip over. twitter:description has no fallback: where og:description drops back to the company Social Description, the Twitter tag is simply left out, so a page with no summary unfurls on X with a title and nothing else. And twitter:image has the extra logo fallback described above.

Reading time is computed from the page’s stored word count divided by your site’s reading speed — 200 words per minute unless you set a different Reading Speed, rounded down, with a floor of one minute.

<meta property="og:locale" content="en-us">
<meta property="og:site_name" content="Leed" />
<meta property="og:site" content="https://leed.ai" />
<meta property="og:title" content="Publishing your first page" />
<meta property="og:description" content="A walk through the Deploy screen, from pending change to live URL." />
<meta property="og:image" content="https://leed.ai/cdn-cgi/imagedelivery/.../social" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="413" />
<meta property="og:url" content="https://leed.ai/blog/publishing-your-first-page/" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2026-09-01T12:00:00.000Z" />
<meta property="article:modified_time" content="2026-09-04T09:15:00.000Z" />
<meta property="article:publisher" content="Leed" />
<meta property="article:author" content="Ada Lovelace" />
<meta property="article:tag" content="publishing,deployments,getting started" />

Which fields you control, and where

The page editor's Page Settings panel with Summary filled in, several keyword chips and a feature image thumbnail set
What a reader sees on the cardSet inFieldDocumented at
The headlinethe page editorTitlePage Settings
The blurb under itthe page editorSummaryPage Settings
The picturethe page editorFeature ImageUploading Images
The site name beside itSettings → GeneralSite TitleSite Identity and Branding
The @handle attributionSettings → GeneralTwitter IDSite Identity and Branding
The per-author attributionthe author’s own profileTwitter ID on a visible profileYour Profile
Whether the card says articleSettings → Page TypesShow In FeedsConfiguring a Page Type
The blurb on a page with no summarySettings → GeneralSocial DescriptionSite Identity and Branding
The card shape and the fallback imagerepository site dataogCard.cardType, ogCard.imageGlobal Site Data

The settings-level Social Title and Social Description are worth one more sentence, because their labels oversell them: the templates prefer the page’s own title and summary and use these only when the page has neither. On a real published page — which always has a title — Social Title never applies. Fill in the page’s own summary rather than reaching for the site-wide default.

An author only reaches article:author or twitter:creator if their profile is marked visible; an invisible profile is skipped silently in both.

Structured data

Where it does apply, a page-type slug of blog produces BlogPosting for an article and Blog for a paginated list page.

FieldSourceAlways present
@contextthe literal https://schema.orgyes
@typeBlogPosting, or Blog on a paginated list pageyes
@idthe page’s absolute URLyes
urlthe page’s absolute URLyes
headlinethe page titleyes
datePublishedpublishedAtyes
dateModifiedmodifiedAtyes
publisher.namesite titleyes
publisher.logosite logo, made absoluteyes
publisher.descriptionsite descriptionyes
imagethe feature imageonly when the page has one
keywordsthe page’s keywordsonly when the page has some
descriptionthe page summaryonly when the page has one
wordCountthe page’s stored word countonly when it is non-zero
author[]one Person per visible author, as givenName and familyNameonly when at least one author is visible

Note that authors are emitted as separate given and family names, with no combined name — a consumer expecting author.name will find nothing there.

If you need structured data on a page type Leed does not cover, write it yourself. A <script type="application/ld+json"> block in your own layout gives you per-type control, and one in header-includes.hbs reaches every page of the site including the documentation — see How Templates Work and Customizing the <head>. The built-in block comes from the JSON-LD helper, which is one of the content helpers and needs triple braces because it emits raw HTML.

Checking a card before you share it

Publish the page first, then paste its live URL into the platform’s own card inspector — every major platform runs one, and each caches results independently, so a card that looks stale in one place may be current in another.

What the common failures mean:

  • No image. The page has no feature image and your site data sets no ogCard.image. On an Open Graph consumer there is no image tag at all; on X you will see your site logo instead.
  • An empty or wrong description. The page has no summary. Open Graph fell back to your Social Description; the Twitter card omitted the tag entirely.
  • The card says website where you expected article. The page type’s Show In Feeds is off.
  • The card is a small square where you wanted a wide banner. twitter:card defaults to summary; a wide preview needs ogCard.cardType set to summary_large_image in your site data.

One reminder that catches people out: a preview site is noindex from top to bottom, and crawlers are told to stay away. Test the card against the live URL, not the preview one — Preview Site vs Live Site covers the other differences.

ESC