Skip to content
Sneferu
by Hekana

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

starter/layout/theme.snf
<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" />
Result
A collection page with the header above and product cards below
A page with the default header; the footer sits below.

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:

groups/header.json
{
  "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:

json
"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

ts
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.