Meridian handbook
ReferenceConfiguration

site.yaml

Every key of config/sites/<key>/site.yaml: the site name, hosts, country, time zone, locales and URL strategy, navigation slots, template roots, SEO and robots, accessibility statement, widgets, headless delivery, assets, mail sender and outbound links.

Each directory under config/sites/ is a site, named by its key (lower case letters, digits and hyphens). Its site.yaml holds the site’s identity, hosts, locales, navigation slots, SEO and delivery; its routes.yaml holds the URLs. A site may also have endpoints.yaml, images.yaml, plugins.yaml, promotions.yaml, portal.yaml and its own schema/.

site:
  name: { en-GB: Wyndmouth }
  timezone: Europe/London
  country: GB
  default_currency: GBP
  domains: [www.wyndmouth.example]
  default: true

templates:
  roots: [wyndmouth, _shared]

locales:
  strategy: prefix
  enabled: [en-GB, fr-FR]
  default: en-GB

seo:
  title_template: "{{ title }} | {{ site.name }}"
  sitemap: { enabled: true }
  robots: { enabled: true, disallow: ["/studio"] }

engine-dmo dev site add writes a new site’s directory with its id. See Sites, locales and routes.

KeyTypeDefaultMeaning
accessibility.alt_fallbackstringwarnWhat publishing does when an image’s alt text would show from a fallback locale: allow, warn or block
accessibility.alt_fallback_localesmap of stringPer locale, the policy for alt text shown from a fallback locale
accessibility.conformancestringThe standard claimed, such as WCAG 2.2 AA
accessibility.contact_emailstringWhere accessibility problems are reported
accessibility.last_reviewedstringWhen the statement was last reviewed
accessibility.statement_pathstringThe path of the site’s accessibility statement
assets.budgetsmap of stringSize budgets by kind (css, js, legacy_css, legacy_js), each the total across the site’s bundles, such as 120KB
assets.bundlesmap of stringmain: src/entries/<site>.jsThe site’s entries by bundle name, each a path relative to the project. Another name defaults to src/entries/<site>-<name>.js
assets.externalbooleanfalseThe site is built by a toolchain of its own: the Vite integration builds no entry for it and the asset helpers read assets.manifest
assets.manifeststringpublic/build/.vite/manifest.jsonA Vite manifest, relative to the project, for an external site
delivery.frontend.originstringFor a headless site, the frontend’s origin; every canonical and absolute URL is built on it. https in production
delivery.frontend.preview_urlstringThe frontend’s preview route, with {token}, and optionally {path}, {document} and {locale}. https in production
delivery.frontend.webhookslist of objects[]Receivers told what changed, so the frontend can revalidate
delivery.frontend.webhooks[].eventslist of stringEvery eventThe change events to send
delivery.frontend.webhooks[].secretstringRequiredA secret of at least 16 characters, as ${VAR}, the deliveries are signed with
delivery.frontend.webhooks[].urlstringRequiredThe frontend’s revalidation route; https in production
delivery.modestringrenderedrendered (the engine renders pages) or headless (a separate frontend reads the content API)
embed.enabledbooleanfalseServe the embeddable widgets under server.embed_path
embed.map.attributionstringThe tile credit. Required with tiles
embed.map.max_zoominteger16The map widget’s highest zoom
embed.map.tilesstringA tile URL template for the map widget, such as https://tiles.example.org/{z}/{x}/{y}.png. Without it the map is drawn from its markers alone
embed.max_itemsintegerCaps every list widget, whatever a caller asks for
embed.onlybooleanfalseEmbed-only mode: every page the site serves carries noindex, because the content ranks on the website that embeds it
embed.originslist of string[]The origins allowed to embed the widgets by script tag or frame
embed.thememap of string{}CSS custom properties the widget shell sets, so a widget matches the page it sits on
links.outbound.new_tabbooleanfalseOpen links to other websites in a new tab, announced as such, with noopener
links.outbound.rellist of string[]rel tokens every link to another website carries, such as nofollow
locales.defaultstringRequiredThe site’s default locale
locales.domainsmap of stringWith strategy: domain, the host of each locale
locales.enabledlist of stringRequiredThe locale codes the site runs, from locales.yaml
locales.fallbackmap of list of string{}Per locale, the locales whose text shows where it has none, overriding the install’s fallbacks for this site
locales.strategydomain, prefix, prefix-allprefixHow a locale shows in URLs: prefix (every locale but the default under /<code>/), prefix-all (every locale prefixed) or domain (a host per locale)
mail.fromstringmail.fromThe site’s transactional sender
mail.newsletter.dkim_selectorslist of stringnewsletter.dkim_selectorsThe DKIM selectors checked for the site’s sending domain
mail.newsletter.from_addressstringnewsletter.from_addressThe site’s own newsletter sender address
mail.newsletter.from_namestringnewsletter.from_nameThe site’s own sender name
mail.newsletter.reply_tostringnewsletter.reply_toThe site’s own reply address
mail.reply_tostringmail.reply_toThe site’s Reply-To
memberships.tierslist of stringEvery tierThe tiers this site sells (engine-dmo)
navmap of any{}The navigation slots the templates print, by name, each { id, label, depth }. The items are edited in the admin
seo.default_imagestringThe social sharing image used when a page has none
seo.robots.agentslist of objectsGroups for named crawlers, written after the group for every crawler: a crawler that finds its name obeys only its own group
seo.robots.agents[].allowlist of stringPaths this crawler may fetch
seo.robots.agents[].disallowlist of stringPaths this crawler may not fetch
seo.robots.agents[].user_agentstringRequiredThe crawler’s name
seo.robots.allowlist of stringPaths reopened under a disallowed one, for every crawler
seo.robots.disallowlist of stringPaths no crawler may fetch
seo.robots.enabledbooleanServe /robots.txt from these rules
seo.sitemapmap of anyThe sitemap: enabled, max_urls_per_file
seo.structured_data.breadcrumbsbooleantrueEmit a BreadcrumbList from the real URL hierarchy
seo.structured_data.organisationanytrueThe destination as the publisher of the site: true, false, or a mapping with its type, logo and other properties
seo.structured_data.searchbooleantrueEmit the WebSite search action where the site routes search
seo.title_templatestringThe page title pattern, such as `“{{ title }} \
settingsmap of any{}Free values your templates read as site.settings
siteobjectRequiredThe site itself
site.countrystringThe site’s ISO 3166 country code, which decides country conventions (address formats, the financial year)
site.defaultbooleanfalseThe install’s default site. Exactly one
site.default_currencystringThe site’s ISO 4217 currency
site.domainslist of stringRequiredThe host names the site answers on, with a port where one is used (localhost:8080). *.example.org matches subdomains. A host belongs to one site
site.idstringWritten for youThe element’s stable id. Written by engine-dmo check --fix; never write or change it by hand
site.namemap of stringRequiredThe site’s name per locale
site.networkstringThe default networkThe network the site belongs to (networks.yaml)
site.organisationstringThe organisation that runs the site, for structured data and statements
site.path_prefixstringA path the whole site lives under on its host
site.positionintegerThe site’s order in the admin
site.short_namemap of stringA shorter name per locale
site.timezonestringThe site’s IANA time zone
templates.allow_unescapedbooleanfalseAllow {% autoescape off %} and the safe filter in this site’s templates
templates.rootslist of string[<site>, _shared]The template directories searched, in order