Built-in metadata vocabularies
Four built-ins describe a document to something outside your docs site. A platform schema says what your generator will parse. A taxonomy schema says what kind of page this is. These four say how the page presents itself to a social card renderer, a catalogue, or another publisher’s build.
| Id | Speaks to | Requires |
|---|---|---|
ogp:article:1.0 |
Social and link-preview renderers | og:title, og:type, og:url, og:image |
dcmi:elements:1.1 |
Catalogues, repositories, library systems | nothing |
microsoft:learn:1.0 |
The Microsoft Learn publishing build | title, description, author, ms.author, ms.date |
x:cards:1.0 |
X, when someone shares the link | twitter:card |
ogp:article:1.0
Section titled “ogp:article:1.0”The Open Graph protocol basic properties plus the article
object type. This is the built-in that checks something no build tool
checks. Nothing fails when og:image is missing. The page builds and deploys
perfectly, then renders as a grey box everywhere it is shared.
In HTML these live on <meta property="…">. docmeta reads property alongside
name, so an ordinary HTML page needs no special handling:
<meta property="og:title" content="Validate document metadata in CI" /><meta property="og:type" content="article" /><meta property="og:url" content="https://example.com/docs/ci" /><meta property="og:image" content="https://example.com/img/card.png" />In front matter they are ordinary keys, quoted because they contain a colon:
---"og:title": Validate document metadata in CI"og:type": article---Fields
Section titled “Fields”| Property | Type | Notes |
|---|---|---|
og:title |
string | Required. Non-empty. |
og:type |
string | Required. Not enumerated, because the protocol allows namespaced and vendor types. |
og:url |
URI | Required. Absolute. A site-root path is not a canonical URL. |
og:image |
URI | array | Required. |
og:description |
string | One or two sentences. |
og:site_name |
string | |
og:determiner |
enum | a, an, the, "", auto. |
og:locale |
string | language_TERRITORY, such as en_US. |
og:locale:alternate |
string | array | Same form. |
og:audio, og:video |
URI | array | |
article:published_time |
date-time | ISO 8601. |
article:modified_time |
date-time | ISO 8601. |
article:expiration_time |
date-time | ISO 8601. |
article:author |
string | array | |
article:section |
string | |
article:tag |
string | array |
dcmi:elements:1.1
Section titled “dcmi:elements:1.1”The fifteen elements of the Dublin Core Metadata Element Set, as published in
the DCMI Recommendation of 2020-01-20. That date is worth noticing: this is a
frozen specification, so unlike the toolchain pins, 1.1 will stay accurate
indefinitely.
contributor, coverage, creator, date, description, format,
identifier, language, publisher, relation, rights, source,
subject, title, type.
DCMI marks no element mandatory, so the schema requires nothing. Every element is repeatable in Dublin Core, so each accepts a single value or a list:
---creator: - Ada Lovelace - Charles Babbagedate: 2026-08---date is the one element with a format. It is encoded as W3CDTF, which permits
reduced precision, so 2026, 2026-08, and 2026-08-23 are all valid. A full
datetime carries a timezone. June 5th is not.
microsoft:learn:1.0
Section titled “microsoft:learn:1.0”The front matter Microsoft Learn requires and recommends on a documentation article. Of every built-in, this is the closest analogue to what docmeta itself does: five attributes whose absence fails a real publishing build.
| Attribute | Type | Notes |
|---|---|---|
title |
string | Required. |
description |
string | Required. 75–300 characters. |
author |
string | Required. The author’s GitHub account ID, not a display name. |
ms.author |
string | Required. Microsoft alias, without @microsoft.com. |
ms.date |
string | Required. MM/DD/YYYY. |
ms.topic |
string | The kind of article. Not enumerated. |
ms.service, ms.subservice |
string | |
ms.custom, ms.collection, ms.devlang, keywords |
string | array | |
ms.reviewer |
string | |
ms.prod, ms.technology |
string | For repos that use ms.prod instead of ms.service. |
zone_pivot_groups |
string |
Three of these encode a rule that a generic check would miss:
ms.dateisMM/DD/YYYY, not ISO 8601.2026-08-23is the correct spelling nearly everywhere else and is wrong here;08/23/2026is right. Aformat: datecheck would have passed the wrong one.descriptionhas a floor, not just a ceiling. Microsoft documents the hard range as 75–300 characters and recommends 115–145. Only the hard range is enforced, because the recommendation is guidance and the range is the build rule.ms.authorrejects an email address. The alias goes in bare, and writing the full address is the common error.
x:cards:1.0
Section titled “x:cards:1.0”The twitter:* meta tags that decide how a link renders when someone shares it
on X. It is the companion to ogp:article:1.0, on the same <meta> channel and
through the same extractor. The two normally ship together, which is why a site
with Open Graph tags and no card tags is the usual half-finished state.
<meta name="twitter:card" content="summary_large_image" /><meta name="twitter:site" content="@exampledocs" /><meta name="twitter:title" content="Validate document metadata in CI" /><meta name="twitter:description" content="Fail the build when frontmatter is missing." /><meta name="twitter:image" content="https://example.com/img/card.png" />| Field | Type | Notes |
|---|---|---|
twitter:card |
summary | summary_large_image | app | player |
Required. |
twitter:site, twitter:creator |
string | A handle, with or without the @. |
twitter:site:id, twitter:creator:id |
string | integer | Numeric account ids. |
twitter:title |
string | 70 characters. |
twitter:description |
string | 200 characters. |
twitter:image |
string | An HTTPS URL. |
twitter:image:alt |
string | 420 characters. |
twitter:player, twitter:player:stream |
string | HTTPS URLs. Player cards. |
twitter:player:width, twitter:player:height |
string | integer | Pixels. |
twitter:app:* |
string | Name, id, and URL per platform, plus twitter:app:country. |
Why only twitter:card is required
Section titled “Why only twitter:card is required”Every other tag on the card has an Open Graph fallback: X reads og:title,
og:description and og:image when the twitter: equivalents are absent. A
page carrying good Open Graph tags and no twitter:title is correct, so
requiring one here would fail it.
twitter:card is the exception. It has no fallback, and X will not infer a card
type from Open Graph alone. Without it no card renders at all, however complete
the rest of the markup is. That is the whole of what this schema insists on.
The length caps are real limits rather than style advice: X truncates past them.
And twitter:image must be HTTPS, because an image served over plain HTTP is
dropped and the card renders without it.