This reference describes the current @blockbite/astro implementation. Every
rule below is enforced: a file that breaks one fails to load, with the file and
key in the error.
Folders
| Rule | Value |
|---|---|
| Location | src/islands/<family>/<variant>/ |
| An island | A variant folder that contains fields.yaml |
| Folder names | Lowercase letters, digits and -; at most 64 characters |
| Island path | family/variant, at most 128 characters |
| Symbolic links | Not allowed for island folders or files |
| Islands per project | At most 256 |
Folders without fields.yaml are ignored, so a family can also hold shared
components.
fields.yaml
version: 1
fields:
title:
type: string
label: Title
entries:
type: repeater
label: Entries
fields:
title: { type: string, label: Title }
| Property | Rule |
|---|---|
version |
Required. Always 1. |
fields |
Required. A map of 0–128 fields; the key is the field’s identity and component prop. |
| Field key | 1–64 characters: letters, digits and _, starting with a letter or _. Unique among its siblings. __proto__, prototype and constructor are reserved. |
type |
Required. string, markdown, link, image, svg, heading-tag or repeater. |
label |
Required. 1–200 characters, not only spaces. |
fields (repeater) |
Required for a repeater: a map of 1–128 scalar fields. Rows cannot contain another repeater. |
options (svg) |
Required for an SVG field: 1–64 unique approved SVG library keys. |
- A declaration holds at most 512 fields, counting repeater children.
- Any other property, such as
id,key,requiredordefault, is rejected. - The file is read as YAML 1.2 with the core schema, so a date or
yesstays text. Only maps and text, number or boolean values are read; arbitrary lists, aliases and empty values are rejected. - The file is limited to 64 KiB.
link holds one destination string: a site path, #fragment, HTTP(S), mailto:
or tel: address. markdown holds one paragraph with emphasis, strong text,
inline code and links. Raw HTML, images and block formatting are rejected in that
field. Render it with MarkdownInline from @blockbite/astro/markdown-inline;
ordinary {value} interpolation remains plain text. Markdown fields currently
require native Astro output; WordPress/Twig and EmDash exports reject them.
heading-tag holds exactly h1–h6, separately from heading text and styling.
For a configured root heading, bind it through a direct constant alias such as
const { title, titleTag: Title } = Astro.props and render
<Title class="text-4xl">{title}</Title>. Each independent heading needs its own
field and consumer. Siteboard changes the selected placement’s JSON value and
preserves the shared component and its typography classes. Markdown headings,
repeater tags, shared-component forwarding and automatic conversion of fixed
headings are outside this control; the EmDash pilot also rejects this field.
namespace.json
Only families published to a CMS have this file. It holds the project’s only generated IDs.
{
"version": 1,
"templateId": "tpl-ri27rkqrgxvq",
"name": "Editorial grid",
"defaultVariant": "three-up",
"variants": { "three-up": "48qqztws0rcl" }
}
| Property | Rule |
|---|---|
version |
Required. Always 1. |
templateId |
Required. tpl- followed by 6–32 lowercase letters or digits. Unique in the project. |
name |
Required. 1–200 characters, not only spaces. |
defaultVariant |
Required. One of the folder names in variants. |
variants |
Required. 1–128 entries, each a variant folder name mapped to an ID of 6–32 lowercase letters or digits. |
- Every listed variant folder must contain a
fields.yaml. - Variant IDs are unique across the whole project.
- A variant folder without an entry is not published and needs no ID.
- Any other property is rejected, and the file is limited to 16 KiB.
Page JSON
{
"version": 1,
"template": "default",
"title": "Home",
"sections": [
{ "island": "hero/simple", "fields": { "heading": "Welcome", "intro": "" } }
]
}
| Property | Rule |
|---|---|
version |
Required. Always 1. |
template |
Required. One of the template names passed to createPageSchema(). |
title |
Required. At most 512 characters. |
sections |
Required. At most 1,000 sections, in display order. |
island |
The variant’s family/variant path, registered by loadIslands(). |
fields |
Exactly the keys the variant declares. |
- A
stringvalue is text of at most 65,536 characters. An empty string is valid. - A
repeatervalue is a list of at most 1,000 rows. Each row is an object with exactly the repeater’s child keys. - There are no defaults, no
nullvalues and no type conversion. Unknown properties, including old ID properties such aspageIdorrowId, are rejected.
Package exports
| Export | Purpose |
|---|---|
blockbite() from @blockbite/astro |
The integration. Validates blockbite.config.json and the island folders, watches them, and generates island types into .astro/integrations/_blockbite_astro/islands.d.ts. |
loadIslands(directory) from @blockbite/astro/islands |
Reads the island folders and returns islands, namespaces and the files read. Throws an IslandLoadError that lists every problem. |
IslandProps<'family/variant'>, IslandPath |
Component prop types and the union of island paths, from the generated declaration. |
createPageSchema({ islands, templates }) from @blockbite/astro/content |
The page schema for a native content collection. |
defineIsland(), createIslandValuesSchema(), toIslandProps() |
Validate a declaration in code, validate one section’s values, and derive component props from them. |
compileTwigIsland() from @blockbite/astro/twig |
Experimental. Turns an island into a WordPress Twig template, or reports what is outside the supported subset. |
blockbite export wordpress, or exportWordPress() from @blockbite/astro/export |
Experimental. Writes every island listed in a namespace.json as a WordPress snapshot: Twig template, fields, JSON Schema and bundled script. |
blockbite.config.json sets where snapshots go and how many are kept:
{ "build": { "directory": "../exports/my-site", "retention": 5 } }
build.directory defaults to .blockbite/builds and may be outside the project,
but not the project itself or src/, public/ or node_modules/.
build.retention defaults to 5. An unchanged project reuses its latest snapshot,
and a failed export writes nothing.
The package is not published to npm yet.