Audience: Contributor
Instance JSON for reusable block masters — persisted shape, overrides, and what not to serialize.
See also: Page structure · Models · Blocks overview
Reusable blocks are edited as their own content trees and referenced from pages via lkt-block instance nodes. Understanding the instance shape prevents the most common serialization bug: expanding the master into the page.
| Artifact | What it is | Stored where |
|---|---|---|
| Block master | Named reusable tree (IBlockDefinition with children) |
Blocks collection (own content row) |
| Block instance | Reference node on a page/template | Inside a page’s children |
Editing the master updates every instance (edit-once). Instances may override individual props locally.
{
"type": "lkt-block",
"props": [
{
"name": "blockId",
"type": "none",
"value": { "raw": 42 }
}
]
}
Optional local overrides:
{
"type": "lkt-block",
"props": [
{ "name": "blockId", "type": "none", "value": { "raw": 42 } }
],
"data": {
"overrides": {
"ion-title_0|text_0": [
{ "name": "html", "value": { "raw": "Custom title" } }
]
}
}
}
Override keys are paths relative to the block root (same type_index scheme as runtime element ids).
At runtime, BlockOps.resolveChildren(masterChildren, overrides) deep-clones the master and applies overrides. ElementModel.definition for an instance calls BlockOps.createInstance and returns the reference form — never the expanded master.
{
"type": "lkt-block",
"props": [{ "name": "blockId", "type": "none", "value": { "raw": 42 } }],
"children": [ /* expanded master copy — WRONG */ ]
}
builder/block/schema.json, type const lkt-block (BLOCK_ELEMENT_TYPE / BLOCK_ID_PROP = 'blockId').page.schema.json. Schema may list actions, but ElementModel.definition for an instance returns only BlockOps.createInstance(...) — actions/validators on the instance do not round-trip.builder/ is skipped) — instances are created via BlockOps, not the normal palette catalog path.lkt-block + blockId).data.overrides).blockId if masters were remapped.