Check here before asking for a feature
What HERON can already do
Before you write "HERON needs a change", find the need in these tables. If it is here, do it with the site and the theme. If not, look at "What is missing" at the bottom: some things are missing on purpose.
Links in the "Where" column: the contract parts site folder (§1–3), page format (§4), site.yaml (§5), theme.yaml (§6), images and files (§7); build is specification 21; distribution is specification 23.
In plain words
This page is the list of what HERON already knows how to do, sorted by task. Read it before asking for something new: most of what a site needs is already here, it may just have a different name than you expect.
Example. You want the same page to appear in two sections of the site. You search this page for «section» and find «a page in several sections: flat and through links» — no new feature needed, just links between pages.
You need this page when planning a site or when an agent is about to say «HERON needs a change». The last table lists what is missing on purpose and why.
Structure and addresses
| The site needs | How in HERON | Where |
|---|---|---|
A page at /about/ |
the file content/en/about.md (in its language folder) |
contract §2 |
| A section with a catalog of its children | a folder with _index.md; children are files next to it; the template gets page.children |
contract §2, build §4 |
| An address that differs from the file name | the slug field |
contract §2 |
Different addresses in different languages (/guides/ and /ru/rukovodstva/) |
the same file name, a slug in the second language's file |
contract §2 |
| A page type and its own template | type in the file or children_type in the section's _index.md; the template templates/TYPE.html |
contract §4.2 |
A single page with its own layout (about.md) |
type: about in the file, templates/about.html in the theme |
contract §4.2 |
| Order in the catalog and menu | order |
contract §4.2 |
| Menu | nav in site.yaml, by keys; the home page is "/" |
contract §4.2, §5 |
| A short name in the menu and breadcrumbs | nav_title |
contract §4.2 |
| Breadcrumbs | built on their own: page.breadcrumbs |
build §6 |
| A draft that is not built | published: false (--drafts turns it on) |
contract §4.2 |
| A new page with the full SEO block and placeholders for the type's sections | heron page TYPE NAME; new/init write the home page and 404 |
build §10 |
| Comments in site files in Russian or English | --notes ru|en, HERON_NOTES, build.notes |
distribution §4 |
| A section of 100+ pages | one catalog page without pagination; the theme does the grouping | build §4 |
Languages
| The site needs | How in HERON | Where |
|---|---|---|
| One language, two, N | site.languages, site.default_lang |
contract §3 |
The main language at the root, the others under a language prefix (/ru/) |
always like this | contract §3 |
hreflang, x-default |
generated on their own | contract §3 |
| A language switch, an inactive item when there is no translation | languages, lang, page.translations in the template |
contract §3 |
| The second language is written before the main one | a dev build passes with a warning; a prod build with an empty main language gives E021 |
contract §3 |
| A link in the text leads to the page in the same language | write it by key, without a prefix, for example /guides/x/ |
contract §2 |
Site name and title suffix per language |
site.name_ru, seo.title_suffix_ru (and so for every language) |
contract §5 |
| Address, phone, company description per language | contact.address_ru and the like in their blocks; substitutions and the theme pick the language themselves |
contract §5 |
| Theme interface strings ("Read more" / "Читать далее") | theme/i18n/en.yaml and a file per language; t.KEY in the template |
build §7 |
Page content
| The site needs | How in HERON | Where |
|---|---|---|
| An intro and a subheading | text before the first section: lead and promise |
contract §4.3 |
| A block the theme puts in the right place | a section ## Title {#anchor} |
contract §4.3 |
| A list, "term — explanation" pairs | list |
contract §4.4 |
| Warning signs | list with the class .alert → alert-list |
contract §4.4 |
| "How we work" steps, with labels | a numbered list → steps |
contract §4.4 |
FAQ (and FAQPage in the structured data) |
### Question? groups without lists → faq |
contract §4.4 |
| A checklist of documents | three or more ### groups with lists → checklist |
contract §4.4 |
| "Suits / does not suit" | two ### groups with lists → two-lists |
contract §4.4 |
| Short facts like "format — in person" | key | value lines → facts |
contract §4.4 |
| A comparison table | a markdown table → table |
contract §4.4 |
| A timeline | facts or a numbered list with the class .timeline |
contract §4.4 |
| A tip box | a > quote → callout (and section.callout for any section) |
contract §4.4 |
| A gallery | a list of images with the class .gallery |
contract §4.4 |
| Site-wide data: reviews, trust figures, company details | yaml in data/, data.FILE in the template |
contract §1 |
| Raw HTML in markdown | forbidden by default (E015); build.allow_raw_html: true |
contract §5 |
How each form looks on this site: the forms reference.
Relations
| The site needs | How in HERON | Where |
|---|---|---|
| "Related services", "articles on the topic" | a link field in the front matter, declared in theme.yaml links |
contract §6 |
| A reverse list ("where it is mentioned") | back: on the link |
contract §6 |
| A link within one type | allowed | contract §6 |
| A caption on a link | {slug: name, note: "…"} |
contract §6 |
| A warning when a link is not filled in | required and on |
contract §6 |
Images and files
| The site needs | How in HERON | Where |
|---|---|---|
| Responsive images, WebP/AVIF | a path in media/, picture() in the template |
contract §7, build §8 |
| Card ratios | images.ratios in theme.yaml; illustrations are fitted, photos are cropped |
contract §7.6 |
| PDF, video, any file | in media/, the address from media_url() |
contract §7.2, §7.4 |
| A page video | video, video_poster, video_title |
contract §7.5 |
| Scans without resizing | images.as_is |
contract §7.3 |
favicon, webmanifest, .well-known |
static/ |
contract §7.8 |
SEO and service files
| The site needs | How in HERON | Where |
|---|---|---|
| sitemap | generated: one file or an index per language | build §9 |
| robots.txt | generated; dev gets Disallow: / |
build §9 |
llms.txt, full texts for AI assistants |
generated; facts about the site from seo.llms_note |
build §9, contract §5 |
| JSON-LD | types in theme.yaml types.TYPE.jsonld; data from schema in site.yaml and in the page |
contract §5 |
| Prices in the structured data | forbidden while seo.allow_prices: false; allow with true |
contract §5 |
| Publication and update dates | date, updated, build.updated_from: git |
contract §4.2, §5 |
| Atom feed | seo.feed: TYPE |
build §9 |
| Open Graph, a default image per language | og_* in the page, seo.og_default_image and seo.og_default_image_ru |
contract §4.2, §5 |
301 from old addresses, Cyrillic and %D0%… |
redirect_from in the page |
contract §2 |
| 410 for archives, service paths, doorway pages | gone in site.yaml: exact, /wp/*, /?p=* |
contract §5 |
| A 404 page in every language | content/en/404.md in every language folder |
contract §2 |
| Counters in production only | analytics in site.yaml; dev does not output them |
contract §5 |
| Keep dev out of search | the default; production is build --env prod |
build §10 |
| An nginx image with the site, a smoke check | scripts/site.sh SITE image, smoke, push |
distribution §5 |
What is missing, on purpose or for now
| What is missing | Why, and what to do |
|---|---|
| Catalog pagination | on purpose: one section, one page. Split large sections into sub-sections as folders (build §4) |
| Site search, comments, user accounts | a static site has no runtime. An external service is the theme's choice |
| Loading content with a script | forbidden: numbers and text must be in the HTML (contract §10) |
| Accepting forms | there will be a separate service heron-relay, not built yet. HERON checks a form description in site.yaml (forms, sinks), but nothing receives the POST. For now: phone, email, messengers, an external form |
| Admin panel, database | on purpose: files are the source of truth |
| Scheduled publishing by date | no: published is a flag, date is only a date. Publishing is a commit and a build |
| Yandex Metrica in the starter theme | removed; the key analytics.metrika is accepted, outputting it is up to your theme |
Building on the server (install.sh, deploy.sh) |
described in the deploy specification as the target setup, no scripts yet. Today: an image through site.sh |
If the need is in none of the tables, it is a task for HERON. The template is on the Architect page, part "A task for HERON".
Source
This page mirrors docs/agents/capabilities.md from the prod branch. The repository is updated first: capabilities.md on GitHub. The original is written in Russian.