{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "ogp:article:1.0",
  "title": "Open Graph protocol, article profile",
  "description": "The Open Graph protocol's basic metadata plus the `article` object type. Unusually among the built-ins, this one enforces genuine requirements: the protocol names `og:title`, `og:type`, `og:url` and `og:image` as required for every page, and a page missing one has no valid Open Graph object at all. It is also the built-in that checks something no build tool checks — nothing fails when `og:image` is absent, the page just renders badly everywhere it is shared. In HTML these live on `<meta property=\"…\">`, which docmeta reads alongside `name=`; in front matter they are ordinary quoted keys. See https://ogp.me/",
  "type": "object",
  "required": ["og:title", "og:type", "og:url", "og:image"],
  "additionalProperties": true,
  "$defs": {
    "url": { "type": "string", "format": "uri" },
    "urlList": {
      "if": { "type": "array" },
      "then": { "items": { "$ref": "#/$defs/url" } },
      "else": { "$ref": "#/$defs/url" }
    },
    "textList": {
      "if": { "type": "array" },
      "then": { "items": { "type": "string" } },
      "else": { "type": "string" }
    },
    "timestamp": {
      "type": "string",
      "format": "date-time",
      "description": "An ISO 8601 datetime."
    }
  },
  "properties": {
    "og:title": {
      "type": "string",
      "minLength": 1,
      "description": "The object's title, as it should appear in the graph. Required."
    },
    "og:type": {
      "type": "string",
      "minLength": 1,
      "description": "The object type, such as `article` or `website`. Required. Not enumerated: the protocol allows namespaced and vendor types beyond the published list."
    },
    "og:url": {
      "$ref": "#/$defs/url",
      "description": "The canonical URL, used as the object's permanent id. Required, and absolute — a site-root path is not a canonical URL."
    },
    "og:image": {
      "$ref": "#/$defs/urlList",
      "description": "URL of the image representing the object. Required."
    },
    "og:description": {
      "type": "string",
      "description": "A one- or two-sentence description of the object."
    },
    "og:site_name": {
      "type": "string",
      "description": "The name of the overall site this object belongs to."
    },
    "og:determiner": {
      "type": "string",
      "enum": ["a", "an", "the", "", "auto"],
      "description": "The word preceding the title in a sentence. The protocol lists exactly these five, the empty string among them."
    },
    "og:locale": {
      "type": "string",
      "pattern": "^[a-z]{2,3}(_[A-Z]{2})?$",
      "description": "Locale in `language_TERRITORY` form, such as `en_US`. Defaults to `en_US`. The hyphenated BCP 47 spelling `en-US` is not what the protocol specifies and is rejected here."
    },
    "og:locale:alternate": {
      "if": { "type": "array" },
      "then": {
        "items": { "type": "string", "pattern": "^[a-z]{2,3}(_[A-Z]{2})?$" }
      },
      "else": { "type": "string", "pattern": "^[a-z]{2,3}(_[A-Z]{2})?$" },
      "description": "Other locales this page is available in."
    },
    "og:audio": {
      "$ref": "#/$defs/urlList",
      "description": "URL of audio accompanying the object."
    },
    "og:video": {
      "$ref": "#/$defs/urlList",
      "description": "URL of video accompanying the object."
    },
    "article:published_time": {
      "$ref": "#/$defs/timestamp",
      "description": "When the article was first published."
    },
    "article:modified_time": {
      "$ref": "#/$defs/timestamp",
      "description": "When the article was last changed."
    },
    "article:expiration_time": {
      "$ref": "#/$defs/timestamp",
      "description": "When the article stops being current."
    },
    "article:author": {
      "$ref": "#/$defs/textList",
      "description": "Author profile URLs, or names. Repeated `<meta>` tags collapse to the last one on extraction, so a single string is the usual shape."
    },
    "article:section": {
      "type": "string",
      "description": "The high-level section the article belongs to."
    },
    "article:tag": {
      "$ref": "#/$defs/textList",
      "description": "Tags describing the article."
    }
  }
}
