API reference

Snippets

Snippets are reusable HTML/template building blocks. They can be inserted as a copy in the editor or referenced via {% include "name" %} (then changes take effect everywhere immediately).

Snippet object

{
  "id": 1,
  "name": "header",
  "description": "Hauptnavigation",
  "content": "<header>{% for p in nav() %}<a href=\"{{ p.path }}\">{{ p.title }}</a>{% endfor %}</header>",
  "created_at": 1791191665,
  "updated_at": 1791191665,
  "assets": [{ "asset_id": 3, "name": "header", "kind": "css" }],
  "schema": null,
  "page_layout": null
}

schema: block type schema for the page builder (null = no block type). PUT without schema leaves it unchanged; notes about slots come as warnings in the response.

page_layout: { "label": "Content page", "description": "…", "default": true } offers the snippet as a page layout when creating new pages (null = not offered). Empty label = snippet name; label at most 200, description 2000 characters (400 snippet.layoutTooLong). PUT without page_layout leaves it unchanged, "page_layout": null removes it.

assets: CSS/JS files of the snippet in loading order (when writing, asset_id is enough; non-existent IDs are skipped). They are only loaded on pages that execute the snippet during rendering (include, component, extends; macro snippets on import) – in the page content or head field, not in the SEO title/description. CSS goes into <head>, JS before </body>, each after the page’s files and without duplicates. JS files with ES module syntax (top-level import/export, import.meta) are included – as for pages – as <script type="module">.

name is unique and may contain letters, digits, ., _, - and / (e.g. cards/teaser). It must start with a letter or digit.

GET /snippets 🔑 · GET /snippets/{id} 🔑

List (including content) or a single snippet.

POST /snippets ✏️

{ "name": "footer", "description": "", "content": "<footer>© {{ page.title }}</footer>", "assets": [{ "asset_id": 3 }] }

201, 409 if the name is taken. Optional folder (folder in the admin list); if not specified, it is derived from a prefix in the name (teile/footer → teile).

PUT /snippets/{id} ✏️ · DELETE /snippets/{id} ✏️

Merge update or deletion; without assets in the body, the assignment stays unchanged, "assets": [] removes all. Note: pages that include a deleted snippet via include will produce a render error afterwards.

GET /page-layouts 🔑

The page layouts – snippets with page_layout, sorted by label. The admin dialog New page and integrations (IllusionPublish) offer them for selection:

[
  { "id": 12, "name": "layouts/content", "label": "Content page", "description": "Header, title, blocks, footer",
    "default": true, "has_blocks": true, "html": "{% extends \"layouts/content\" %}\n" },
  { "id": 14, "name": "layouts/contact", "label": "Contact", "description": "Address and form",
    "default": false, "has_blocks": false, "html": "{% extends \"layouts/contact\" %}\n" }
]
  • has_blocks: does the layout output a block area for the page ({% blocks page.blocks %}) – also via extends, include and components? The template code is evaluated (comments and verbatim do not count, overridden blocks with extends including block.super do; snippet names from variables cannot be followed). false means static content – an intended case for pages with fixed content; IllusionCMS never inserts blocks by itself.
  • default: preselected in the dialog (if there are several, the first one wins).
  • html: the HTML a new page gets with this layout (POST /pages with layout_id).

The list is also part of GET /schema (page_layouts); when it changes – including has_blocks through changes to included snippets – the schema.changed webhook reports kind: page_layout.