{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "mkdocs:material:9.7",
  "title": "MkDocs Material front matter v9.7",
  "description": "Front matter read by MkDocs 1.6 and Material for MkDocs 9.7 — the two keys MkDocs itself defines (`title`, `template`), the six Material's own templates read, the three its bundled plugins read, and the eight the blog plugin reads on a post. Nothing is required: MkDocs takes a page title from the `nav`, the first H1 or the file name in turn, so a page with no front matter at all builds and renders. That makes it a pure shape check, and the shapes worth checking are the ones the build accepts and then acts on wrongly — a `hide` entry no template tests for, a `tags` string the search plugin skips, a `date` mapping with no `created`. Pinned to Material 9.7 because 9.7.0 is the last feature release of the line. See https://www.mkdocs.org/user-guide/writing-your-docs/#meta-data and https://squidfunk.github.io/mkdocs-material/reference/",
  "type": "object",
  "additionalProperties": true,
  "$defs": {
    "stringList": {
      "type": "array",
      "items": { "type": "string" }
    }
  },
  "properties": {
    "title": {
      "type": "string",
      "description": "Overrides the page title. MkDocs checks the `nav` entry, then this, then the first H1, then the file name, and stops at the first that answers — so nothing breaks without it."
    },
    "template": {
      "type": "string",
      "description": "The theme template rendering this page, instead of `main.html`. Resolved against the theme's template directory, so a name the theme does not carry fails the build."
    },
    "description": {
      "type": "string",
      "description": "Becomes the page's `<meta name=\"description\">`, and the description on its social card."
    },
    "author": {
      "type": "string",
      "description": "Becomes the page's `<meta name=\"author\">`. One name, not a list — Material renders the value straight into the attribute. The blog plugin's `authors` is a different key."
    },
    "icon": {
      "type": "string",
      "description": "An icon shortcode, resolved as `.icons/<value>.svg` — so `material/cached`, not `material/cached.svg`. Shown beside the page in the navigation."
    },
    "status": {
      "type": "string",
      "description": "A status marker shown in the navigation. `new` and `deprecated` ship with the theme; any other value has to be declared in `theme.extra.status`, so the set is site-configured and not enumerated here."
    },
    "subtitle": {
      "type": "string",
      "description": "Rendered under the page's navigation entry. Added in Material 9.6."
    },
    "hide": {
      "type": "array",
      "description": "Page elements to hide. Material tests membership of this list in its templates and reports nothing for an entry it does not know, so a value outside these six hides nothing and says nothing.",
      "items": {
        "type": "string",
        "enum": ["navigation", "toc", "path", "tags", "footer", "feedback"]
      }
    },
    "tags": {
      "$ref": "#/$defs/stringList",
      "description": "Tags for this page, read by the tags plugin and added to the search index. A list, never a bare string: the search plugin skips a `tags` that is not a list without a word."
    },
    "search": {
      "type": "object",
      "additionalProperties": true,
      "description": "Per-page search options.",
      "properties": {
        "exclude": {
          "type": "boolean",
          "description": "Keeps the page out of the search index entirely."
        },
        "boost": {
          "type": "number",
          "description": "Multiplies the page's search ranking. Copied into the index as written, so a quoted number arrives as a string and ranks nothing."
        }
      }
    },
    "social": {
      "type": "object",
      "additionalProperties": true,
      "description": "Per-page overrides of the social cards plugin's site-level settings.",
      "properties": {
        "cards": {
          "type": "boolean",
          "description": "`false` skips card generation for this page."
        },
        "cards_layout": {
          "type": "string",
          "description": "The layout to render this page's card with, resolved under `cards_layout_dir`."
        },
        "cards_layout_options": {
          "type": "object",
          "additionalProperties": true,
          "description": "Layout options merged over the site-level ones — `title`, `description`, `background_color`, `background_image`, `color`, `font_family`. Left unconstrained beyond its type, because the keys a layout reads are the layout's own."
        }
      }
    },
    "date": {
      "description": "A blog post's date: the date itself, or a mapping carrying `created` plus any other date you want the templates to have. The blog plugin errors on a post with no `date` at all, and on a mapping with no `created`. Typed but not format-checked: MkDocs parses front matter with PyYAML, which resolves several timestamp spellings, so pinning one format here would fail input the plugin accepts.",
      "if": { "type": "object" },
      "then": {
        "type": "object",
        "required": ["created"],
        "additionalProperties": { "type": "string" },
        "properties": {
          "created": { "type": "string" },
          "updated": { "type": "string" }
        }
      },
      "else": { "type": "string" }
    },
    "authors": {
      "$ref": "#/$defs/stringList",
      "description": "A blog post's authors, as identifiers defined in `.authors.yml`. Duplicates are dropped silently, so they are not an error here."
    },
    "categories": {
      "$ref": "#/$defs/stringList",
      "description": "A blog post's categories. Deduplicated the same way as `authors`."
    },
    "draft": {
      "type": "boolean",
      "description": "Holds a post back from the built site. A quoted `\"false\"` is a string, which the post configuration refuses outright."
    },
    "pin": {
      "type": "boolean",
      "description": "Pins a post to the top of the blog views. Defaults to false."
    },
    "readtime": {
      "type": "integer",
      "minimum": 0,
      "description": "Overrides the computed reading time, in minutes."
    },
    "slug": {
      "type": "string",
      "description": "Overrides the URL segment a post is built at, otherwise derived from its title."
    },
    "links": {
      "type": "array",
      "description": "Links shown in a post's sidebar, written in the same shape as `nav`: a path, or a mapping of label to path.",
      "items": { "type": ["string", "object"] }
    }
  }
}
