Header, footer and section groups
Build a header, footer and announcement bar as Sneferu section groups: placed in the layout, shared by every page and edited once by the merchant.
On this page
The header, the footer and an announcement bar are not part of one page: every page shows the same ones. Sneferu calls them section groups. A group is a list of sections that the merchant can add to, remove, reorder, hide and edit, once for the whole store.
Place a group in the layout
<a class="sf-skip" href="#main">{{ t('skip_to_content') }}</a>
<hk-section-group name="announcement" />
<hk-section-group name="header" />
<main id="main" class="sf-main"><hk-slot name="content" /></main>
<hk-section-group name="footer" />
name is header, footer or announcement, written as plain text (SN2017),
in the layout only (SN2018), once each (SN2019). A theme that places no group
keeps its inline header and footer and works as before.
Give the group its first content
groups/<name>.json lists the sections a new store starts with:
{
"sections": [
{
"id": "header",
"type": "header",
"settings": { "show_search": true },
"blocks": [
{ "id": "nav-home", "type": "menu-link", "settings": { "label": { "en": "Home", "ar": "الرئيسية" }, "url": "/" } },
{ "id": "nav-shop", "type": "menu-link", "settings": { "label": { "en": "Shop", "ar": "المنتجات" }, "url": "/products" } }
],
"block_order": ["nav-home", "nav-shop"]
}
]
}Each entry has a type (a section in sections/), optional id (letters,
digits, - and _; unique), settings, blocks (a block may hold blocks one
level deeper) and block_order (a list of block ids that sets the order). The
compiler checks the file: JSON and shape SN3036, unknown section SN3037, ids and
block_order SN3038, blocks as in templates (SN3028, SN3029), a limit of 12
sections per group and 64 KB per file. A file for a group the layout never
places is the warning SN3039.
Without a groups/<name>.json the SDK's default header, footer or announcement
bar is used.
Which sections go where
A section may list where it makes sense:
"templates": ["header"]Entries are page types (product), exact alternates (product.codes) or
groups (header). The builder offers the section only there; leave it out for
"everywhere". A bad list is SN3040; a default section placed where its list
forbids is SN3041. blocks.allowed must name blocks that exist (SN3042).
When the page renders, a section in a group whose list does not name that
group is skipped (SN4014), so a stored group cannot bring a section somewhere
its list rules out.
What the runtime needs
renderPage(artifact, { template, ctx, registry, groups: { header: [...], footer: [...] } });groups is the merchant's saved trees (SectionGroups from
@hekana/sneferu-core: { header?: PageNode[]; footer?: PageNode[]; announcement?: PageNode[] }).
A group that is absent uses artifact.groups (the theme's defaults); []
renders nothing. The trees are shared by every template.
Blocks nest one level: block.blocks in a block template lists its child
blocks, which is how a menu link holds a dropdown.