DocumentationDownload

Document schema and blocks

Nucleo 0.2+Free~43 min readUpdated October 31, 2026

Every page is a JSON document with a tree of nodes: here you find its structure, the validation rules and the available blocks.

On this page

01Overview

Every page, layout, reusable section or popup is a JSON document with a tree of nodes. Every node has a type that refers to a registered block. A block is a folder in nucleo/blocks/ with a block.nucleo.json manifest and a PHP renderer. The manifest declares the properties (content, settings), the style groups, and the allowed children and parents.

When the document is saved, it goes through two phases:

Normalization

Nucleo completes the document, expands the sections and resolves the internal links.

Validation

First the JSON schema is checked, then the rules of the manifests and the checks specific to some blocks.

If there is at least one error, the save fails with the code invalid_document and the list of errors.

Compilation, dynamic slots, CSS and reusable sections are described on the Compiler and runtime page.

All blocks in this chapter are Free.

Blocks have no permissions of their own. The permissions of the ability or command that saves the document apply, see Write abilities and WP-CLI commands.

WooCommerce blocks (woo/*) are registered with the nucleo/register_blocks action and are described on the Integrations page.

02JSON document

Top-level keys

What it does: defines the shape of the document. additionalProperties: false: every other key is an error.

How to use: minimal example:

{
  "schema": 1,
  "kind": "page",
  "root": { "id": "a1", "type": "nc/section", "children": [] }
}

Parameters:

NameTypeAllowed valuesDefaultNote
schemainteger>= 11Required in the schema. If missing, the normalizer sets it to 1 before validation.
kindstringpage, layout, section, popup—Required.
rootnodesee Node—Required. Root of the tree.
metaobjectkey seo defined; other keys free—See meta.seo.
paramsobjectname ^[a-z][a-z0-9_]{0,31}$ → {type, label?, required?}—Parameters of a reusable section. type: text, html, image, link, color, boolean, list.
blocksobjectblock type → integer >= 1—Version of each block the document was written with. It is used by the migrator.

Permissions: those of the document save.

Edition: Free

Known limits:

  • The schema describes params as valid only for kind section, but the validator does not enforce this rule.
  • propertyNames is not applied by the internal validator (see JSON Schema subset). The section expansion checks the parameter names (invalid parameter name). The names in blocks are not checked.
  • A list parameter accepts at most 30 strings.

Node

What it does: describes a block in the tree. content, settings and style are separate: content holds the translatable texts, settings the behavior, style the appearance.

How to use: node example:

{ "id": "a2", "type": "nc/heading",
  "content": { "text": "Tax consulting" },
  "settings": { "level": 1 },
  "style": { "fontSize": { "base": "$text.3xl", "lg": "$text.5xl" } } }

Parameters:

NameTypeAllowed valuesDefaultNote
idstring^[a-z0-9]{1,12}$—Required. Unique in the document.
typestring^[a-z][a-z0-9-]*/[a-z][a-z0-9-]*$, registered block—Required.
contentobjectkeys declared in content of the manifest—
settingsobjectkeys declared in settings of the manifestmanifest defaultThe normalizer adds the missing defaults.
styleobjectstyle keys, parts, custom—See Style values.
visibilityobjectbreakpoints, when—See visibility.
bindobjectcontent.<name> or settings.<name> → {source, field, fallback?}—See bind.
childrenarray of nodesaccording to children of the manifest—
refstring^(section):[0-9]+$—Legacy form: reference by id to a section. Excludes children.
guideobject{ "distinct": string 1–200 characters, not only spaces }—Note for nucleo guide: the block is intentionally similar to another one and does not count among the repetitions of rule R1.5.

Permissions: those of the document save.

Edition: Free

Known limits:

  • ref and children together are a schema error.
  • An invalid id produces a single error with the correct suggestion: lowercase letters and digits, truncated to 12 characters (use "abc123").
  • A duplicate id is reported on the second occurrence (duplicate id).

meta.seo

What it does: sets the title and SEO meta of the page when no SEO plugin is active.

How to use: "meta": { "seo": { "title": "...", "description": "...", "noindex": false } }. The use on the page is described on the Integrations page.

Parameters:

NameTypeAllowed valuesDefaultNote
titlestringmax 70 characters—
descriptionstringmax 170 characters—
imagestringformat: uri—The format is not checked (see limits).
noindexboolean——
breadcrumbsboolean——false: no automatic BreadcrumbList on the page.
schemaarray of objectsmax 10; each object has @type ^[A-Z][A-Za-z]{2,60}$—schema.org nodes of the page. The value "@business" refers to the company of the site.

Permissions: those of the document save.

Edition: Free

Known limits: seo does not accept other keys besides those listed. The validator ignores format.

Style values

What it does: each key of style is a CSS property in camelCase with a simple value or an object per breakpoint.

How to use: "padding": "$space.4" or "padding": { "base": "$space.4", "md": "$space.6" }. The references $group.key are tokens, see the Design tokens page.

Parameters:

NameTypeAllowed valuesDefaultNote
<key>string, number, or objectobject with at least one key among base, md, lg, xl—The key must belong to a supports.style group of the block.
<key>Hover, <key>Currentas above——States. Only for color, background, border, borderTop, borderRight, borderBottom, borderLeft, boxShadow, opacity, filter, fontWeight, textDecoration.
partsobjectname of the part declared by the block → style keys—Groups allowed in a part: size, spacing, typography, color, border, effects, layout, motion.
customobjectselector starting with & → CSS property → string or number—Free CSS for what the keys do not cover.

Permissions: those of the document save.

Edition: Free

Known limits:

  • A string value cannot contain ;, {, }, <, >, \, /*, */ or control characters. It cannot contain url(, expression(, @import, image-set(, image(, cross-fade(, element(, src( or javascript:. Parentheses and quotes must be closed. An empty string is not allowed.
  • A cited token that does not exist in the site tokens produces unknown token.
  • Selector of custom: ^&[a-zA-Z0-9_ .:>#()+~*,="'\[\]-]*$. Property of custom: ^-{0,2}[a-z][a-z0-9-]{0,60}$.
  • Keys with a closed list (position, overflow*, textDecoration, textTransform, whiteSpace, fontStyle, alignSelf, justifySelf and others) reject other values. zIndex accepts an integer between -9999 and 9999.
  • The values of motion have their own validation.

visibility

What it does: hides the node by breakpoint (CSS) or by condition (dynamic slot).

How to use: "visibility": { "breakpoints": { "base": false, "lg": true }, "when": [{ "is": "logged_in" }] }. The effect at runtime is described on the Compiler and runtime page.

Parameters:

NameTypeAllowed valuesDefaultNote
breakpointsobjectbase, md, lg, xl → boolean—
when[].isstringlogged_in, logged_out, role:<slug> ([a-z0-9_-]+), filled, empty—Required.
when[].sourcestringpost, nucleo, item, acf, metabox, jetengine, author, term, site—Required with filled and empty.
when[].fieldstringnot empty—Required with filled and empty.

Permissions: those of the document save.

Edition: Free

Known limits: in the cards of nc/query, nc/collection and in the rows of nc/repeater only filled and empty are allowed (code card_block_not_allowed).

bind

What it does: connects a property of the node to a dynamic value.

How to use: "bind": { "content.text": { "source": "post", "field": "title", "fallback": "—" } }. Sources and resolution are described on the Dynamic data page.

Parameters:

NameTypeAllowed valuesDefaultNote
keystringcontent.<name> or settings.<name> declared by the block—A key not declared produces bind key not declared in the block.
sourcestringpost, term, author, site, nucleo, acf, metabox, jetengine, woo, user, query, param, item—Required.
fieldstringnot empty—Required.
fallbackstring——

Permissions: those of the document save.

Edition: Free

Known limits:

  • The validator accepts every property declared by the block. It ignores supports.bind of the manifest.
  • Inside a reusable section, the keys style.<name>, visible and repeat are handled by the expansion and removed before validation (see Compiler and runtime).
  • In the cards, the sources user and query are not allowed (card_block_not_allowed).

03Validation

Order of checks

What it does: validation returns the list of all errors. It does not stop at the first one.

How to use: the save and nucleo/doc-validate use it. For each node, in this order:

  1. JSON schema of the document.
  2. Registered type. If missing, the error lists all registered types in allowed.
  3. id: rule and uniqueness.
  4. Allowed parent (parents of the manifest).
  5. content and settings: declared keys, type and constraints of each property, required fields, keys of the elements with item.
  6. style: supported group, allowed value, safe CSS, existing token. Then style.parts and style.custom.
  7. bind: declared key.
  8. Checks specific to the block: nc/query, nc/collection, nc/repeater, nc/native-form, nc/embed.
  9. nc/icon: icon name.
  10. URLs in settings.href and content.src.
  11. visibility.when.
  12. Allowed children (children of the manifest), then recursion into the children.

Parameters: the normalized document.

Permissions: those of the calling ability or command.

Edition: Free

Known limits:

  • Property types of the manifests that are not JSON types (inline-rich-text, rich-text) are validated as string.
  • Errors with the same path and the same message appear only once.
  • Without tokens the token check is skipped. The site validator always passes the site tokens.
  • Errors on nodes that come from a section point to the nc/section-ref of the document.

Error format

What it does: every error says where, what and how to fix it.

How to use: every error has this shape:

{ "path": "/root/children/0/settings/level", "message": "...", "got": 7,
  "allowed": [1, 2, 3, 4, 5, 6], "fix": "...", "code": "card_missing", "guide": "R3.3" }

Parameters:

NameTypeAllowed valuesDefaultNote
pathstringJSON Pointer—Always present.
messagestring——Always present, translated.
gotany——Absent if null.
allowedlist——Absent if empty.
fixstring——Suggested fix.
codestringsee Error codes—Absent for schema errors.
guidestringR3.3, R4.3—Rule of nucleo guide linked to the code.

Permissions: —

Edition: Free

Known limits: on save, the result is invalid_document with the message Invalid document.. If there are style_group_unsupported errors, the message lists them all in one sentence, with the place to move each key.

Error codes

What it does: stable codes for agents. The other errors have only message.

How to use: read code in the errors list of the result.

Parameters:

CodeBlockWhen
style_group_unsupportedallThe style key belongs to a group that the block does not have. fix suggests the children that have the group, or a doc-patch wrap in nc/container, or the blocks that have the group.
card_missingnc/queryMore than one child.
card_missingnc/repeaterNumber of children different from 1.
card_missingnc/collectionNumber of nc/collection-card different from 1, or a card with more than one child.
card_block_not_allowedcards of nc/query, nc/collection, nc/repeaterBlock not allowed in the card, source user or query, visitor condition, nc/repeater nested in a row.
field_missingnc/repeatersettings.field empty.
card_term_sourcenc/collectionCard of a terms collection that reads the post or sources other than term.
unknown_componentnc/collection, nc/native-formSource or action component not registered.
unknown_post_typenc/collection, nc/native-formContent type not allowed or not in the model.
unknown_taxonomync/collectionTaxonomy not public, or not linked to the content type.
unknown_termnc/collectionsettings.parent is not a term of the taxonomy.
unknown_fieldnc/collection, nc/native-formField that does not exist or of a type not allowed.
terms_no_filtersnc/collectionterms collection with filters or sorting.
duplicate_keync/collectionFilter or sort key repeated, or sort or page.
bad_uinc/collectionui not allowed for the filter type.
duplicate_fieldnc/native-formField name repeated.
bad_optionsnc/native-formselect, radio or checkboxes field without options.
bad_stepnc/native-formField step outside the steps of the form.
otp_firstnc/native-formotp action not in first position, or field not of type email.
otp_stepnc/native-formstep of the otp action not consistent with the steps.
unverified_recipientnc/native-formemail action with to: "field:<name>" without otp on the same field.
bad_statusnc/native-formcreate-post with a status other than draft or pending.
unsafe_urlnc/native-form, nc/embedwebhook with a URL that is not https://; settings.url of nc/embed that is not https://.
invalid_urlnc/embedYouTube or Vimeo address without a valid video id.

Permissions: —

Edition: Free

Known limits: only these codes link to a rule of nucleo guide: card_missing and card_block_not_allowed (R3.3), and component_code (R4.3).

URL check

What it does: rejects dangerous URLs in settings.href and content.src of every node.

How to use: automatic. The check accepts http, https, mailto, tel and the relative ones that start with / (not //), # or ?.

Parameters: none.

Permissions: —

Edition: Free

Known limits:

  • settings.href also accepts an internal reference: home, page:<slug>, post:<slug>, <post-type>:<slug>, term:<taxonomy>/<slug>. Resolution is described on the Compiler and runtime page.
  • The check covers only the two top-level keys. It does not cover settings.parent.href of nc/breadcrumbs, content.poster of nc/video, settings.redirect of nc/native-form, or settings.url of nc/embed, which the block checks itself. The renderers of nc/video and nc/button filter their own values.

JSON Schema subset

What it does: the internal validator, without dependencies, checks the document and the properties of the manifests.

How to use: internal.

Parameters: keywords applied: type, enum, const, $ref (only #/$defs/...), allOf, anyOf, oneOf, not, properties, patternProperties, additionalProperties, required, minProperties, items, minItems, maxItems, minLength, maxLength, pattern, minimum, maximum.

Permissions: —

Edition: Free

Known limits:

  • The other keywords are ignored, among them format, propertyNames, uniqueItems.
  • min and max are also ignored, used by the manifest of nc/slider. Only the renderer applies the limits of perView, autoplay and speed.
  • An empty array is valid both as an array and as an object.

04Normalization, versions and migrations

Normalizer

What it does: completes the document before validation and compilation.

How to use: the normalizer runs these steps, in this order:

  1. A missing schema becomes 1.
  2. Block migrations.
  3. Defaults of the settings from the manifest, for every node with a registered type. Explicit values stay.
  4. Node with ref: "section:N": becomes the root of section N. The internal ids get the prefix g<N>, truncated to 12 characters. The node keeps its own id. The referenced document does not follow other ref.

Parameters: none.

Permissions: —

Edition: Free

Known limits:

  • The defaults apply only to settings, not to content.
  • An unresolved ref stays as it is.
Warning

The save stores the raw document, not the normalized one.

Schema version

What it does: schema is the version of the document format.

How to use: write "schema": 1.

Parameters: none.

Permissions: —

Edition: Free

Known limits: the list of document migrations is empty. At version 0.2.0 there are no document migrations.

Block migrations

What it does: brings every node to the current version of its block, with operations declared in the manifest.

How to use: in the manifest, migrations maps the arrival version to a list of operations:

"migrations": { "2": [ { "op": "rename", "from": "settings.size", "to": "settings.level" } ] }

Parameters:

NameTypeAllowed valuesDefaultNote
op: renamefrom, todotted path ^[a-zA-Z_][a-zA-Z0-9_-]*(\.…)*$—Only if from exists and to does not.
op: removepathdotted path—
op: setpath, valuedotted path—Only if path does not exist.

Permissions: —

Edition: Free

Known limits:

  • The migrations applied are those with a version greater than the one saved in blocks and less than or equal to the current one, in numeric order.
  • A document without the block version in blocks does not migrate: the system records only the current version.
  • All 41 blocks are at version 1 and have migrations empty or absent.

Compact format

What it does: reduces the document for an agent.

How to use: used by nucleo/doc-get.

Parameters:

NameTypeAllowed valuesDefaultNote
nodeIdstringid of a nodenullReturns only that subtree. Missing id: not_found error.
depthinteger>= 0nullNodes at depth >= depth lose children and get childCount. Negative: invalid_op error.

Permissions: those of the ability.

Edition: Free

Known limits: removes content, settings, style, visibility, bind when empty, and the settings equal to the default. It does not change the tokens.

Document patch

What it does: describes the operations of nucleo/doc-patch.

How to use: an array of semantic operations by id (insert, move, remove, set, duplicate, wrap) or JSON Patch RFC 6902 by path (add, replace, test, remove, move, copy).

Parameters: see the Write abilities chapter.

Permissions: those of the ability.

Edition: Free

Known limits: baseRevision sits in the patch container, not in the array.

05Block manifests

Manifest fields

What it does: Nucleo reads the block.nucleo.json manifest of every folder in nucleo/blocks/. An invalid manifest blocks the loading with an error that names the file.

How to use: one folder per block with block.nucleo.json, style.css and an optional view.js. The renderers of the nc/* blocks are included in the plugin.

Parameters:

NameTypeAllowed valuesDefaultNote
namestring^[a-z][a-z0-9-]*/[a-z][a-z0-9-]*$—Required. Unique: a duplicate is an error.
versioninteger>= 1—Required.
titlestringnot empty—Required.
categorystring—general
description, aiHintsstring—""aiHints are the instructions for the agent returned by nucleo/catalog-get.
content, settingsobjectname → {type, translatable?, required?, default?, item?, …}{}JSON Schema subset. item describes the keys of each element of an array.
supports.styleliststyle groups—The registry adds the base groups. See Style groups.
supports.styleExcludelistsize, spacing, typography, color, border, motion—Base groups that the block does not receive.
supports.responsive, supports.visibility, supports.bind———Informational: nucleo/catalog-get returns them, the validator does not read them.
partsobjectname ^[a-z][a-zA-Z0-9]{0,30}$ → selector inside the node{}Styleable parts for style.parts.
childrenboolean or list of types—falsetrue: any child. List: only those types.
parentsnull or list of types—nullnull: any parent.
assets.style, assets.scriptstring or nullpath relative to the folder—
assets.strategystringeager, visible, interaction, idleeagerLoading of the script, see the Optimizer and assets page.
semanticsobjectheading, image, link, landmark, text, embed{}Used by the quality engine. landmark takes tagFrom (field with the tag) or tag (fixed tag), and ifFrom (field that must have a value).
rendererstringclass that implements Nucleo\Blocks\Renderer""If the class does not exist, Nucleo loads Renderer.php from the block folder.
depslist^[a-z_]+(?::[A-Za-z0-9_.{}-]+)*$[]Invalidation keys, for example menu:{settings.menu}.
migrationsobjectsee Block migrations—

Permissions: —

Edition: Free

Known limits: the error Renderer "<class>" not found for block <type> appears only at the first compilation of the block, not at loading.

Style groups

What it does: every style key belongs to a group. A block accepts only the keys of its groups.

How to use: every block receives the base groups size, spacing, typography, color, border, motion, except supports.styleExclude. The groups declared in supports.style are added. The list of each block is in its section. The CSS output is described on the Compiler and runtime page.

Parameters:

GroupKeys
spacingpadding, margin, gap
sizewidth, maxWidth, minWidth, maxHeight, minHeight, height, aspectRatio
colorcolor, background, accentColor
typographyfontSize, fontWeight, lineHeight, letterSpacing, fontFamily, fontStyle, textAlign, textDecoration, textTransform, whiteSpace
layoutdisplay, columns, direction, wrap, justify, align, order, flexGrow, flexShrink, flexBasis, alignSelf, justifySelf
borderborder, borderTop, borderRight, borderBottom, borderLeft, borderRadius, boxShadow
effectsopacity, objectFit, filter, transform
positionposition, top, right, bottom, left, inset, zIndex, scrollMarginTop, overflow, overflowX, overflowY
motionanimation, animationDuration, animationDelay, transition
menuitemColor, itemColorHover, itemColorActive, itemBackground, itemBackgroundHover, itemBackgroundActive, itemDecoration, itemDecorationHover, itemWeight, itemWeightActive, itemPadding, itemRadius, itemGap, submenuBackground, panelWidth, panelBackground
controlscontrolBackground, controlColor, controlBorder, controlRadius, controlPadding, controlFocus
buttonsbuttonBackground, buttonColor, buttonBorder, buttonRadius, buttonPadding
choicescontrolBackgroundActive, controlColorActive, controlBorderActive, popoverBackground
resultsresultsColumns, resultsGap
carouselcontrolSize, dotColor, dotColorActive, controlsInset
linklinkColor, linkColorHover, linkDecoration, linkDecorationHover
fieldslabelColor, labelSize, labelWeight, helpColor, legendColor, legendSize, legendWeight, legendLine, markColor, optionalColor, optionalSize, optionalWeight, numberSize, numberBorder, numberColor, numberFont, numberFontSize, numberWeight, controlMinHeight, controlBorderHover, placeholderColor, checkSize, checkAccent, navJustify, fieldGap, fieldMinHeight

Permissions: —

Edition: Free

Known limits: an unknown key produces unknown style property. A known key of a group that the block does not have produces style_group_unsupported.

Third-party blocks

What it does: a plugin registers its own blocks.

How to use:

add_action('nucleo/register_blocks', function (Nucleo\Blocks\Registry $r) {
    $r->register(__DIR__ . '/blocks/hero');
});

Parameters: folder with block.nucleo.json.

Permissions: —

Edition: Free

Known limits: the action runs once, when Nucleo builds the block registry. A name already registered is an error.

06Structure blocks

nc/section

What it does: full-width band with an inner container div.nc-section__inner.

How to use: "type": "nc/section". Parents: any. Children: any.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.tagstringsection, header, footer, main, div, aside, navsectionExternal HTML element.
settings.anchorstring——Becomes id only if it matches ^[a-z][a-z0-9-]{0,63}$.

Style: spacing, size, color, border, layout, position, motion, typography.

Permissions: those of the document save.

Edition: Free

Known limits: a non-compliant anchor produces no error: the renderer omits the id. The settings.tag sets the landmark semantics.

nc/container

What it does: flex or grid container for columns and groups of blocks. With href and label it becomes a clickable card.

How to use: "type": "nc/container". Parents: any. Children: any.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.layoutstringflex, gridflexClass nc-container--flex or --grid.
settings.responsiveModestringmedia, container—container: the node gets container-type:inline-size.
settings.anchorstring——As in nc/section.
settings.hrefstringURL or internal reference—With label, adds a link a.nc-container__link that covers the container.
settings.labelstring——Accessible name (aria-label) of the link.

Style: spacing, size, color, border, effects, layout, position, motion, typography.

Permissions: those of the document save.

Edition: Free

Known limits: the link appears only with both href and label not empty. A javascript:, data: or vbscript: scheme removes the link.

nc/spacer

What it does: empty vertical space. Prints <div aria-hidden="true">.

How to use: "type": "nc/spacer" with style.height. Children: none.

Parameters: none.

Style: size, color, motion.

Permissions: those of the document save.

Edition: Free

Known limits: the manifest excludes color with styleExclude but declares it among the supported styles. The declared group wins: color stays allowed.

nc/divider

What it does: horizontal line <hr>.

How to use: "type": "nc/divider". Children: none.

Parameters: none.

Style: spacing, size, color, border, motion, typography.

Permissions: those of the document save.

Edition: Free

Known limits: none found.

nc/section-ref

What it does: inserts a reusable section (nucleo_section) by slug, with the parameter values.

How to use:

{ "id": "p1", "type": "nc/section-ref",
  "settings": { "section": "product-card", "params": { "title": "Magnesium" } } }

Children: none. Expansion, dependencies and recompilation are described on the Compiler and runtime page. nucleo/section-list lists the sections.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.sectionstring^[a-z0-9][a-z0-9_-]{0,199}$—Required. Slug, not id.
settings.paramsobjectparameter name → value of the declared type—

Style: no group (all the base groups are excluded).

Permissions: those of the document save. Drafts and private sections are used only if the saving user has edit_theme_options, or if there is no logged-in user (WP-Cron, WP-CLI).

Edition: Free

Known limits:

  • The renderer prints an empty string: the node is replaced before compilation.
  • Maximum 4 levels of nested sections.
  • Expansion errors: section slug missing, section loop, too many nested sections, section has no root, undeclared parameter, required parameter without value or default, use a value of type …, legacy ref not supported inside a reusable section.

07Text blocks

nc/heading

What it does: heading from h1 to h6.

How to use: "type": "nc/heading". Children: none. The supported binding is content.text.

Parameters:

NameTypeAllowed valuesDefaultNote
content.textinline-rich-text——Required, translatable.
settings.levelinteger1–62

Style: typography, color, spacing, border, size, motion.

Permissions: those of the document save.

Edition: Free

Known limits: the text is cleaned to the allowed tags: strong, em, b, i, br, p, ul, ol, li, span[class], a[href,target,rel]. Other tags lose the markup and keep the text. script and style disappear with their content.

nc/text

What it does: paragraph with limited rich text, in a <div>.

How to use: "type": "nc/text". Children: none. The supported binding is content.html.

Parameters:

NameTypeAllowed valuesDefaultNote
content.htmlinline-rich-texttags allowed for rich text—Translatable.

Style: typography, color, spacing, border, size, motion. Part: link (the link in the text).

Permissions: those of the document save.

Edition: Free

Known limits: same cleaning as nc/heading.

nc/list

What it does: bulleted list <ul>, with an optional icon in front of each item.

How to use: "type": "nc/list". Children: none.

Parameters:

NameTypeAllowed valuesDefaultNote
content.itemsarray of stringsrich text—Required.
settings.iconstringicon name—Same icon for every item.

Style: typography, color, spacing, motion, size, border. Parts: item (the li), icon (the icon inside the li).

Permissions: those of the document save.

Edition: Free

Known limits: the validator does not check settings.icon. An unknown name does not print the icon, without error. Non-string items are skipped.

08Media blocks

nc/image

What it does: image with srcset, sizes, LCP priority or deferred loading, and <picture> with modern formats.

How to use: "type": "nc/image". Children: none.

Parameters:

NameTypeAllowed valuesDefaultNote
content.srcstringallowed URL—Required.
content.altstring——Ignored with decorative.
content.width, content.heightinteger> 0—Written only if positive.
content.srcset, content.sizesstring——Without srcset, for an image of the media library the compiler uses the WordPress srcset with the intermediate sizes of the attachment, and writes the file's width and height if they are missing. Without sizes, inside an ancestor with a numeric style.columns, sizes follows the column width per breakpoint, for example (min-width: 768px) min(33.33vw, 1280px), min(100vw, 1280px). Outside columns and with a known width: (max-width: Wpx) 100vw, Wpx.
content.idstringdigits—Attachment id. Otherwise the renderer looks it up from the URL.
content.sourcesarray{type, srcset}; type: image/avif, image/webp, image/png, image/jpeg—Manual sources of <picture>: they win over the automatic ones.
settings.decorativeboolean—falsealt="" and no LCP priority.
settings.formatsstringauto, offautooff: no <picture>.

Style: size, border, effects, spacing, position, motion, typography, color.

Permissions: those of the document save.

Edition: Free

Known limits: the first non-decorative image of the document gets fetchpriority="high", the others loading="lazy". The automatic sources require the site option imageFormats.

nc/icon

What it does: inline SVG icon. A site icon wins over an internal icon with the same name.

How to use:

{ "id": "i1", "type": "nc/icon", "settings": { "name": "phone" } }

Children: none. Site icons are added with nucleo-icons-set or with the CLI (nucleo icons import, nucleo icons add, see the Local CLI page).

Parameters:

NameTypeAllowed valuesDefaultNote
content.labelstring——With label: role="img" and aria-label. Without: aria-hidden="true".
settings.namestring^[a-z][a-z0-9-]{0,40}$, internal or site icon—

Style: size, color, spacing, motion, typography, border.

Permissions: those of the document save.

Edition: Free

Known limits:

  • Internal icons (25): check, arrow-right, phone, mail, map-pin, star, menu, close, plus, minus, clock, truck, wrench, shield, calendar, info, external-link, chevron-down, car, bus, tractor, search, gauge, layers, refresh.
  • An unknown name produces unknown icon with the list in allowed.
  • The internal icons use a 24×24 grid, currentColor stroke.

What it does: site logo (the WordPress custom logo) with explicit width and height, or the site name. Linked to the home page.

How to use: "type": "nc/logo". Children: none.

Parameters: none.

Style: size, spacing, motion, typography, color, border.

Permissions: those of the document save.

Edition: Free

Known limits: the logo is written on save. The site dependency recompiles the document when it changes.

nc/video

What it does: YouTube or Vimeo video with a static thumbnail. The iframe loads on click.

How to use: "type": "nc/video". Children: none. Script view.js, strategy interaction.

Parameters:

NameTypeAllowed valuesDefaultNote
content.providerstringyoutube, vimeo—Required.
content.videoIdstringYouTube ^[A-Za-z0-9_-]{6,20}$; Vimeo digits only—Required. A non-compliant id becomes empty.
content.titlestring——Required, translatable. Button name: Play: <title>.
content.posterstringhttps://… or a path starting with /—Without poster: i.ytimg.com thumbnail for YouTube, no image for Vimeo.
settings.consentstringmarketing, statistics, preferences, nonemarketingCategory of the consent plugin.

Style: size, border, motion, spacing, typography, color.

Permissions: those of the document save.

Edition: Free

Known limits: with a consent plugin active and consent other than none, the block shows The video loads after cookie consent.. The provider thumbnail waits for consent. A custom poster loads at once.

nc/slider

What it does: carousel. Effect slide (scroll-snap) or fade (one slide at a time). Arrows, dots, autoplay with a pause button.

How to use: "type": "nc/slider". Each child is a slide. Children: any. Script view.js, strategy visible.

Parameters:

NameTypeAllowed valuesDefaultNote
content.labelstring—GalleryAccessible name of the carousel.
content.prevLabel, nextLabel, pauseLabel, playLabelstring—translated textsButton names.
settings.perViewinteger1–41Ignored with fade.
settings.arrowsboolean—true
settings.effectstringslide, fadeslide
settings.autoplayinteger0–300Seconds between slides. With a value > 0 the pause button appears.
settings.loopboolean—true
settings.dotsboolean—false
settings.controlsPositionstringbelow, bottom-left, bottom-right, bottom-centerbelowOutside below the controls sit over the slides.
settings.speedinteger100–3000500Milliseconds, variable --nc-slider-speed.
settings.pauseOnHoverboolean—true

Style: spacing, border, motion, controls, carousel, size, typography, color.

Permissions: those of the document save.

Edition: Free

Known limits:

  • The manifest uses min and max, which the validator ignores. A value out of range passes validation and the renderer brings it back into range.
  • The default button names use the language of the user who saves. For a site in another language, write them in content.

nc/embed

What it does: YouTube or Vimeo video, Google Maps or another https address, with a static thumbnail. The iframe loads only on click.

How to use:

{ "id": "e1", "type": "nc/embed",
  "content": { "title": "Guided visit" },
  "settings": { "url": "https://youtu.be/abcDEF12345", "aspectRatio": "4:3" } }

Children: none. Script view.js, strategy interaction.

Parameters:

NameTypeAllowed valuesDefaultNote
content.titlestring——Required, translatable. Button name: Load: <title>.
content.posterstringhttps://… or a path starting with /—Without poster: i.ytimg.com thumbnail for YouTube, no image for the others.
settings.urlstringhttps:// to YouTube, Vimeo, Google Maps or another site—Required.
settings.aspectRatiostring16:9, 4:3, 1:1, 21:916:9Proportion of the video area.
settings.consentstringmarketing, statistics, preferences, nonemarketingCategory of the consent plugin, as in nc/video.

Style: size, spacing, typography, color, border, motion.

Permissions: those of the document save.

Edition: Free

Known limits:

  • The validator reports unsafe_url if settings.url is not https://, and invalid_url if the YouTube or Vimeo address has no valid id. With an invalid address the renderer prints nothing.
  • YouTube (youtube.com, m.youtube.com, youtube-nocookie.com, youtu.be) requires an id of 6–20 characters. Vimeo (vimeo.com, player.vimeo.com) requires a numeric id. Google Maps is recognized separately. Every other https becomes a generic iframe.
  • With a consent plugin active and consent other than none, the provider thumbnail waits for consent and The content loads after cookie consent. appears.

09Action and interactive blocks

nc/button

What it does: link with the look of a button. Without href it is a <button type="button">.

How to use: "type": "nc/button". Children: none. The supported binding is content.text.

Parameters:

NameTypeAllowed valuesDefaultNote
content.textstring——Required, translatable.
settings.hrefstringURL or internal reference—
settings.variantstringprimary, secondary, linkprimaryClass nc-button--<variant>.
settings.newTabboolean—falsetarget="_blank" rel="noopener".

Style: typography, color, spacing, size, border, motion.

Permissions: those of the document save.

Edition: Free

Known limits: an href with a javascript:, data: or vbscript: scheme turns the link into a <button>.

nc/accordion

What it does: expandable sections with details and summary. Optional: JSON-LD FAQPage.

How to use: "type": "nc/accordion". Children: none. No script.

Parameters:

NameTypeAllowed valuesDefaultNote
content.itemsarray{title: string, html: rich-text}, both required—Required, translatable.
settings.openFirstboolean—falseFirst item open.
settings.faqboolean—falseAdds <script type="application/ld+json"> FAQPage.
settings.iconstringchevron, pluschevronplus: class nc-accordion--plus.

Style: spacing, color, typography, border, motion, size. Parts: item, summary, panel.

Permissions: those of the document save.

Edition: Free

Known limits: the nucleo/faq_schema filter with false removes the JSON-LD. Items with an empty question or answer do not enter the JSON-LD.

nc/tabs

What it does: ARIA tabs (tablist, tab, tabpanel). Without JavaScript all the panels stay visible.

How to use: "type": "nc/tabs". Children: none. Script view.js, strategy idle.

Parameters:

NameTypeAllowed valuesDefaultNote
content.itemsarray{title: string, html: rich-text}, both required—Required, translatable.

Style: spacing, color, typography, border, motion, size. Parts: tab, panel.

Permissions: those of the document save.

Edition: Free

Known limits: generated ids <id>-tab-N and <id>-panel-N. Without valid items the block prints nothing.

11Post and archive blocks

These blocks are dynamic: the compiler writes a slot, and the runtime fills it on every request. Inside a card they read the post of the item, otherwise the request object.

nc/post-title

What it does: title of the current post.

How to use: "type": "nc/post-title". Children: none.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.tagstringh1, h2, ph1
settings.linkboolean—falseThe title becomes a link to the post.

Style: typography, color, spacing, link, motion, size, border. Part: link.

Permissions: those of the document save.

Edition: Free

Known limits: outside a post it prints nothing.

nc/post-content

What it does: content of the requested post, passed through the the_content filter.

How to use: once in the single layouts. Children: none.

Parameters: none.

Style: typography, color, spacing, motion, size, border. Part: link.

Permissions: those of the document save.

Edition: Free

Known limits: it always reads the request object, not the card. A guard prevents recursion. Not allowed in cards.

nc/post-image

What it does: featured image of the post, with <picture> and modern formats.

How to use: "type": "nc/post-image". Children: none.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.sizestringregistered size, ^[a-z0-9_-]+$largeNon-compliant value: large.
settings.priorityboolean—falsefetchpriority="high" and loading="eager". Otherwise lazy.
settings.formatsstringauto, offauto

Style: spacing, size, border, effects, motion, typography, color.

Permissions: those of the document save.

Edition: Free

Known limits: without a featured image it prints nothing.

nc/post-meta

What it does: date, author, categories and taxonomy terms of the post.

How to use:

{ "id": "m1", "type": "nc/post-meta", "settings": { "fields": ["date", "tax:genre"] } }

Children: none.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.fieldsarray of strings`^(date\author\categories\tax:[a-z0-9_-]+)$`["date"]The date goes in <time datetime>.
settings.termsstringtext, chipstextchips: class nc-post-meta--chips, terms without commas.

Style: typography, color, spacing, motion, size, border. Parts: item, term, link.

Permissions: those of the document save.

Edition: Free

Known limits: tax: shows only the visible taxonomies. Without items it prints nothing.

nc/archive-title

What it does: title of the archive without the prefix ("Category:"). With a search: Results for: <query>.

How to use: "type": "nc/archive-title". Children: none.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.levelinteger1, 2, 31

Style: typography, color, spacing, motion, size, border.

Permissions: those of the document save.

Edition: Free

Known limits: empty title: no output.

nc/archive-description

What it does: description of the archive, filtered with wp_kses_post.

How to use: "type": "nc/archive-description". Children: none.

Parameters: none.

Style: typography, color, spacing, motion, size, border.

Permissions: those of the document save.

Edition: Free

Known limits: empty description: no output.

12List and collection blocks

The cards of nc/query, nc/collection and the rows of nc/repeater follow these rules:

  • Blocks not allowed: nc/query, nc/collection, nc/pagination, nc/form, nc/native-form, nc/search, nc/breadcrumbs, nc/archive-title, nc/archive-description, nc/post-content, nc/menu, nc/mega-panel and every woo/*.
  • Bind sources not allowed: user, query.
  • Allowed visibility.when conditions: only filled and empty.

The error is always card_block_not_allowed. Binding and runtime of the cards are described on the Dynamic data page.

nc/query

What it does: list of posts built on save. With relatedTo it becomes a slot: posts related to the current post, computed on every request and cached.

How to use: without children it uses a fixed card: medium_large image, h2 title with link, excerpt. With one child, the child is the card repeated for each post. Children: at most 1. Dependency query:{settings.postType}.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.postTypestringregistered content typepostNon-existent type: empty list.
settings.perPageinteger1–246
settings.taxonomystringtaxonomy slug""Fixed filter, with term.
settings.termstringterm slug""
settings.relatedTostringtaxonomy slug""Posts of the same type with a term in common, excluding the current one.
settings.orderbystringdate, titledatedate descending, title ascending.
settings.emptystring—No contentText without results. With relatedTo, "" prints nothing.

Style: spacing, layout, typography, color, position, motion, size, border.

Permissions: those of the document save.

Edition: Free

Known limits:

  • Only published posts without password.
  • Cache of relatedTo: group nucleo_related of the object cache, with persistence of 24 hours. Without a persistent object cache, the value goes into the _nucleo_related meta of the current post.
  • The default No content is in English and the renderer translation does not apply.

nc/repeater

What it does: repeats the child (the row) for each row of a repeater field of the current post. Dynamic.

How to use: one child with bind {"source": "item", "field": "<subfield>"}. The source item also offers index, from 1. Children: exactly 1.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.fieldstringkey of a repeater field of the model""Empty: field_missing error.
settings.tagstringdiv, ul, oldivWith ul and ol each row is in li.nc-repeater__item.
settings.emptystring—""Text without rows. Empty: no output.

Style: spacing, layout, typography, color, motion, size, border.

Permissions: those of the document save.

Edition: Free for the block. The repeater field of the content model is Pro.

Pro

The block reads only the repeater fields of the Nucleo content model.

Known limits: a nc/repeater inside a row is not allowed (card_block_not_allowed). index does not replace a subfield with the same name.

nc/collection

What it does: filterable and sortable list of posts, terms or data from a component. Filters and results update without reloading the page.

How to use: allowed children nc/collection-card (exactly one), nc/collection-count, nc/collection-reset, nc/collection-empty. Script view.js, strategy visible. Dependency query:{settings.postType}. Runtime, filter URLs and component sources are described on the Dynamic data page.

Parameters:

NameTypeAllowed valuesDefaultNote
content.filtersLabel, applyLabel, moreLabel, sortLabel, closeLabel, resultsLabel, allLabel, upcomingLabel, pastLabel, monthLabel, fromLabel, toLabel, gridLabel, rowsLabelstring—plugin translationsresultsLabel: {count} or %d; `singular\plural`.
settings.sourcestringposts, component, termsposts
settings.componentstringregistered data source""With source: component.
settings.postTypestringpublic type of the model""With source: posts.
settings.taxonomystringpublic taxonomy, not nav_menu nor wp_*""With source: terms.
settings.parentstring"" (all), "0" (top level), term slug""With source: terms.
settings.hideEmptyboolean—trueWith source: terms.
settings.cardSizestringauto, smallautosmall: minimum column 9rem instead of 16rem.
settings.perPageinteger1–4812
settings.orderbystringposts: date, title, menu_order, field:<key>; terms: name, slug, count, field:<key>posts date, terms namefield: requires a number, date, text or select field.
settings.orderstringasc, descposts desc, terms asc
settings.prefixstring—fPrefix of the URL parameters.
settings.filtersarraymax 12 items[]See below.
settings.sortsarraymax 8; {key, label, orderby, order} all required[]
settings.viewsarraygrid, rows["grid"]
settings.pagingstringpages, more, nonepages
settings.countsboolean—true
settings.mobileFiltersstringdrawer, inlinedrawer

Item of settings.filters (key, label, type, ui required):

typeKeysAllowed ui
taxonomytaxonomy linked to the content type, multiple?pills, select, checkboxes, dropdown
fieldfield of type select or booleanpills, select, checkboxes, dropdown
fieldfield of type number or daterange
datefield? of type date, presets? (upcoming, past, month)pills, select, range
search—text
paramparam declared by the component source. With range you need <param>_min and <param>_max—

Style: spacing, layout, typography, color, position, motion, controls, buttons, choices, border, results, size. resultsColumns: from 1 to 12 columns, also per breakpoint.

Permissions: those of the document save.

Edition: Free

Known limits:

  • Validation codes: unknown_component, unknown_post_type, unknown_taxonomy, unknown_term, unknown_field, terms_no_filters, duplicate_key, bad_ui, card_missing, card_term_source, card_block_not_allowed.
  • Reserved filter and sort keys: sort, page.
  • With source: terms the card cannot contain nc/post-title, nc/post-image, nc/post-meta, nc/repeater, nor sources post, nucleo, item, author, acf, metabox, jetengine.

nc/collection-card

What it does: card of nc/collection. Its only child repeats for each item.

How to use: child of nc/collection, with one child only (for example nc/container). Children: any, within the card rules.

Parameters: none.

Style: base groups. The renderer prints nothing: the style of the node has no visible effect.

Permissions: those of the document save.

Edition: Free

Known limits: the only allowed parent is nc/collection. More than one child: card_missing.

nc/collection-count

What it does: number of results of nc/collection.

How to use: optional child of nc/collection. Children: none.

Parameters:

NameTypeAllowed valuesDefaultNote
content.textstring{count} or %d; two forms `singular\plural`—Without a placeholder the number goes first. A pipe preceded by a backslash is literal; %% writes %. Without text the resultsLabel of the collection applies.
content.onestring——Text for a single result.

Style: typography, color, spacing, size, border, motion. The collection applies the classes of the node.

Permissions: those of the document save.

Edition: Free

Known limits: the only allowed parent is nc/collection.

nc/collection-empty

What it does: content shown by nc/collection when there are no results.

How to use: optional child of nc/collection, for example with an nc/text. Children: any.

Parameters: none.

Style: base groups. The collection prints only the children: the style of the node has no visible effect.

Permissions: those of the document save.

Edition: Free

Known limits: without this block the collection shows nothing when there are no results.

nc/collection-reset

What it does: link that clears the filters of nc/collection.

How to use: optional child of nc/collection. Children: none.

Parameters:

NameTypeAllowed valuesDefaultNote
content.textstring——Text of the link. Translatable.

Style: typography, color, spacing, border, size, motion. The collection applies the classes of the node.

Permissions: those of the document save.

Edition: Free

Known limits: the only allowed parent is nc/collection.

13Code blocks

These two blocks print code that does not pass the style and accessibility checks. They require unfiltered_html.

nc/html

What it does: prints the HTML code as written, inside a div with the classes of the block. WordPress does not filter it.

How to use: "type": "nc/html", "content": { "html": "<p>Text</p>" }. Children: none. Use it only when no other block fits: for rich text prefer nc/text.

Parameters:

NameTypeAllowed valuesDefaultNote
content.htmlstring——Required. Printed without cleaning.

Style: size, spacing, typography, color, border, motion.

Permissions: whoever saves the document must have unfiltered_html, otherwise the content is not kept.

Edition: Free

Known limits: the code is not checked for style or accessibility.

nc/shortcode

What it does: prints the output of a WordPress shortcode, run on every request.

How to use: "type": "nc/shortcode", "content": { "shortcode": "[gallery ids=\"1,2\"]" }. Children: none. Prefer a native block when one exists.

Parameters:

NameTypeAllowed valuesDefaultNote
content.shortcodestringstarts with [ and ends with ]—Required.

Style: size, spacing, typography, color, border, motion.

Permissions: whoever saves the document must have unfiltered_html, otherwise the content is not kept.

Edition: Free

Known limits: the validator checks only the […] form. The shortcode is not verified.

14Form blocks

nc/form

What it does: inserts a form from an external plugin with its shortcode, on every request.

How to use:

{ "id": "f1", "type": "nc/form", "settings": { "plugin": "cf7", "id": "123" } }

Children: none. Dependency form:{settings.plugin}.

Parameters:

NameTypeAllowed valuesDefaultNote
settings.pluginstringcf7, gravity, wpforms, fluent—Required. Shortcode: contact-form-7, gravityform … ajax="true", wpforms, fluentform.
settings.idstring——Required. Id of the form in the plugin.

Style: spacing, typography, motion, size, color, border.

Permissions: those of the document save.

Edition: Free

Warning

The block does not check that the plugin is active. With an empty id it prints nothing.

nc/native-form

What it does: native form with fields, steps and actions: code verification by email, save, email, webhook, post creation, component action.

How to use: "type": "nc/native-form". Children: none. Script view.js, strategy interaction. Submission, captcha, OTP and runtime actions are described on the Dynamic data page.

Parameters:

NameTypeAllowed valuesDefaultNote
content.submitLabel, successMessage, errorMessage, codeLabel, nextLabel, backLabel, sentMessage, sendCodeLabel, verifyLabel, otpFailedMessage, expiredMessage, requiredMark, optionalMark, captchaMessagestring——Translatable.
settings.fieldsarraymax 40[]See below.
settings.stepsarray{title} required[]
settings.actionsarraysee below[]
settings.redirectstringhome, page:<slug>, URL—Empty: the result message stays.
settings.captchaboolean—truefalse removes the site captcha from this form.
settings.groupNumberingstringnone, letters, numbers, letters-box, numbers-boxnoneNumbers the legends of the groups.

Item of settings.fields (name and type required):

KeyTypeAllowed valuesDefault
namestringunique in the form—
typestringtext, email, tel, url, textarea, number, date, select, radio, checkboxes, checkbox, consent, hidden, context—
label, help, placeholder, groupstring——
requiredboolean——
stepinteger>= 0, below the number of steps0
maxLengthinteger>= 1—
min, maxnumber or string——
decimalsinteger>= 0—
optionsarray{value, label?}; required for select, radio, checkboxes—
valuestring or number——
fromstringpost.id, post.title, post.url—
widthstringfull, halffull

Item of settings.actions (type required):

typeKeysRules
otpfield, subject?, body?, ttl (5–30, default 15), step?First action. field of type email. step below the last step and not before the step of the field.
save——
emailto, replyTo?, subject?, body?to: "field:<name>" requires an otp on the same field.
webhookurlOnly https://.
create-postpostType, status, title?, fields?postType of the model. status draft or pending.
componentname, input?Action registered by a plugin.

Style: size, spacing, typography, color, border, motion, controls, buttons, fields. Parts: field, label, legend, number, legendLine, mark, optional, help, control, placeholder, check, nav, button, message.

Permissions: those of the document save.

Edition: Free

Known limits:

  • Validation codes: duplicate_field, bad_options, bad_step, otp_first, otp_step, unverified_recipient, unknown_field, unknown_post_type, bad_status, unsafe_url, unknown_component.
  • The placeholders {field:<name>} in subject, body, title, fields and input must cite a field of the form (unknown_field).
Esc
↑↓ to select↵ to openEsc to closeLocal search, no data sent