Referenz

HeroML

Extending & security

Custom & licensed blocks

Additional blocks arrive as packages (plugins) and register via the API:

export default function register(cms) {
  cms.addBlock({
    type: 'pricing',
    title: 'Pricing table',
    category: 'design',
    scope: ['home'],
    css: '.pricing{ … }',
    render: (props, node, ctx) => `<section class="pricing">…</section>`,
  });
}

The render callback receives the properties, the block node and a context (including ctx.e for escaping and ctx.renderChildren). A package can be licensed and show a locked placeholder without a valid licence; the key is entered under Design → Bookable block packs.

Security & SEO

  • HeroML is data, not code: the parser only builds an object tree — nothing is executed.
  • Block renderers escape every value. Raw HTML exists only via html/richtext and is sanitised by an allowlist.
  • The <head> (title, meta, Open Graph, Twitter, JSON-LD, favicon) is generated centrally; blocks can contribute their own JSON-LD structured data.
  • Output is server-rendered, semantic HTML; sitemap.xml and robots.txt remain unchanged.

Cheat sheet

# comment                      indent: 2 spaces
type attr=value attr2="two words" flag  # block line
key: value                              # field line
  child-block                           # deeper = child

grid cols=3 · cell span=2               # grid
with-sidebar side=right · sidebar sticky # sidebar
featured                                # highlight 50/25/25
posts layout=grid excerpt=20 mode=loadmore
recent-posts count=5 · category-list    # dynamic widgets
ad slot=header format=leaderboard       # ad slot
meta / animate=fade-up / {{ site.title }}

← Back to documentation