An island is a section of a page that editors can fill in. It is an ordinary
Astro component plus a fields.yaml file that declares which values it accepts.
This guide describes the current @blockbite/astro implementation.
Families and variants
Islands are grouped in two folder levels under src/islands/:
src/islands/
hero/ family
simple/ variant
Island.astro
fields.yaml
editorial-grid/ family
namespace.json
three-up/ variant
Island.astro
fields.yaml
swipeable-row/ variant
Island.astro
fields.yaml
- A family is one kind of section, such as a hero or an editorial grid.
- A variant is one design of that section. Content refers to it by its path,
family/variant, for exampleeditorial-grid/three-up. - Folder names use lowercase letters, digits and
-. - A folder becomes an island only when it contains a
fields.yaml. Other folders, such as shared components, are left alone.
Declare the fields
fields.yaml lists the variant’s editable fields. Each key is the field’s
identity and also the name of the component prop:
# src/islands/editorial-grid/three-up/fields.yaml
version: 1
fields:
eyebrow:
type: string
label: Eyebrow
title:
type: string
label: Title
entries:
type: repeater
label: Entries
fields:
title:
type: string
label: Title
meta:
type: string
label: Meta
- Every field has a
typeand alabel. The label is the editor-facing name. stringholds plain text.linkholds one URL,imagean image location, andsvgan approved library key.repeaterholds a list of rows containing scalar fields; rows cannot contain another repeater.markdownholds inline formatted text with links. It stays a Markdown string in your JSON content and needs the native inline component shown below.heading-tagholds anh1–h6value separately from the heading’s text. See the field reference for binding rules.- Fields appear in the order they are written.
- The file contains no IDs. Renaming a key renames the field: update the component and the page content in the same change.
Variants of one family can use the same keys. three-up and swipeable-row
both declare title and entries, so the same values fit both designs.
For an introduction with inline links, explicitly declare the field:
intro:
type: markdown
label: Introduction
Then consume it inside your existing paragraph:
---
import MarkdownInline from '@blockbite/astro/markdown-inline';
const { intro } = Astro.props;
---
<p><MarkdownInline text={intro} /></p>
For example, Explore [our neighborhoods](/neighborhoods/) becomes an actual
link. Bold, italic and inline code also work. This field supports one paragraph;
use native Markdown articles for full documents. Plain string fields keep
their existing behavior. Markdown fields are currently for native Astro sites;
CMS exporters report them as unsupported before writing a package.
Type the component
Island.astro is a normal Astro component. It names its own path and receives
exactly the props its fields.yaml declares:
---
import type { IslandProps } from '@blockbite/astro/islands';
type Props = IslandProps<'editorial-grid/three-up'>;
const { eyebrow, title, entries } = Astro.props;
---
<section class="editorial-grid three-up">
{eyebrow && <p class="eyebrow">{eyebrow}</p>}
<h2>{title}</h2>
<ul>
{entries.map((entry) => <li><h3>{entry.title}</h3><p>{entry.meta}</p></li>)}
</ul>
</section>
You do not write these types yourself. The blockbite() integration generates
them from every fields.yaml into Astro’s .astro/ folder, which is not part
of your source. astro check then reports a component that uses a field its
fields.yaml does not declare.
To enable the integration, add it to astro.config.mjs:
import { defineConfig } from 'astro/config';
import blockbite from '@blockbite/astro';
export default defineConfig({
integrations: [blockbite()],
});
Static and published islands
A family without namespace.json is used only by the site itself and needs no
IDs. Add a namespace.json when a family’s variants are published to a CMS.
It holds the only generated IDs in a project: one for the family and one per
published variant.
{
"version": 1,
"templateId": "tpl-ri27rkqrgxvq",
"name": "Editorial grid",
"defaultVariant": "three-up",
"variants": {
"three-up": "48qqztws0rcl",
"swipeable-row": "m1pdrqtpj3ge"
}
}
The IDs live in the family file, not in the variant folders, so copying a variant folder never copies its identity. Do not write these IDs by hand. Tooling to create them, and publishing itself, are planned.
When something is wrong
The integration checks island folders when Astro starts and reports problems with the file and field key. Correct the named declaration, component prop or content value, then run the project’s checks again.
astro dev watches changes to existing declarations and newly added island
field or namespace files. After changing fields, run npx astro sync --force
to revalidate cached page content.
See the island file reference for every rule and limit, and page content for using islands on a page.