Page head — SEO, meta tags and JSON-LD#
Every published page's <head> is built from two SeoEntity values: the
document's own seo and the site defaults in setup/web.seo. mergeSeo
(compose.ts) combines them; headMetaTags (web_renderer) writes the tags.
WebSite and the admin's Studio renderer both go through these two, so a
preview's head is the published one.
- Generated tags —
og:title(the SEO title, else the document'stitle/name— without the site's title pattern, which only the<title>carries),description+og:description,og:image, the canonical link,og:url,og:locale+og:locale:alternate(path mode with a known origin). - Custom tags —
seo.meta: [{key, value}], a list, so a key may repeat (og:image,article:tag). Keys matchSEO_META_KEY_PATTERN(a letter, then letters / digits /_ . : -);seoMetaListdrops entries with an invalid key or an empty value at render — nothing refuses them on write.seoMetaAttrpicks the attribute: the Open Graph namespaces (og,article,book,profile,music,video,product,fb,business,place) render asproperty=, every other key (twitter:*,robots,author,theme-color) asname=. Values are HTML-escaped. The custom tags follow the generated ones. - Precedence per key (case-insensitive), most specific first: the
document's meta > the document's SEO title / description / image > the
site's meta > the site's SEO fields. A document key drops every site entry
under that key and replaces the generated tag. A site key replaces a
generated tag only where that tag comes from the site's own SEO fields, so
a site
og:imagefills a page without an SEO image but never beats one. A site key underog:url/og:locale/og:locale:alternateis dropped — those are the page's own.metaReplaceslists the generated keys the renderer leaves out. - JSON-LD —
pageJsonldmerges the site'ssetup/web.jsonldrecords with the document's ownjsonld(the Structured Data container); where both declare a@type, the document's record wins. One<script type="application/ld+json">per record; invalid JSON is skipped.
/gen/seo returns a meta list as well (og:type, social og:title /
og:description, twitter:card); the admin's SEO card merges it by key.