# Create your own block type Source: [Create your own block type](https://typeroll.com/docs/guides/create-block-type/) > Ask an AI agent to create an editable block type, validate and preview it, then review and reuse it in the editor. Includes MCP, REST and portal steps. Use a custom block type when a design recurs and editors should fill in fields instead of arranging its pieces. Each placed block keeps its own content; the type owns the shared structure and styling. This is a built-in CMS feature in Cloud and self-hosting, not a Typeroll App or Extension. From Core 0.2.78, **write/editor** permission can create or change a type. Editors can also place available types and edit their values. No local development environment is required. ## First choose the simplest approach * For a one-off layout, combine [built-in blocks](https://typeroll.com/docs/guides/block-library/). * For the same content everywhere, use a [global block](https://typeroll.com/docs/tools/reusable-blocks/). * For a section copied and edited independently, use a **block template**. * For a reusable design with editable fields, create a **block type**. Prefer a **composed** type, built from existing blocks. It keeps their image, link, named-style and responsive behavior. Use a **template** type with your own HTML when built-in pieces cannot express the markup you need. A template block type is unrelated to a full [Page template](https://typeroll.com/docs/guides/page-templates/). ## Recommended: ask your AI agent Creating custom block types is a good task to delegate to an AI agent connected to Typeroll through [MCP](https://typeroll.com/docs/getting-started/mcp-server/). Describe the design, which fields people should edit and how it should behave on mobile. The agent can inspect existing blocks and starters, define the fields, build the composition or markup, and validate and preview it with Typeroll’s tools. You do not need to write the JSON, HTML or CSS yourself. For example: ```text Create a reusable advice callout for this Site and Version. Give editors a heading and advice text to fill in. Use our existing colors and spacing, and compose it from built-in blocks if possible. Check whether a suitable type already exists before creating one. Validate the definition, preview it with short and long text, and place an example on a draft Page for me to review. Do not deploy the site. ``` The agent uses your current Site permissions. From Core 0.2.78, write/editor access is enough to create or change a block type; administrator access is not required. Read-only access cannot save changes. The optional [tr-custom-blocks recipe](https://typeroll.com/docs/skills/tr-custom-blocks/) guides this workflow. With compact MCP discovery, ask the agent to discover the relevant tools as needed. A local repository or development server is not required. Review the result in the editor, test its fields and inspect narrow and wide previews. Once the type is available, editors can add instances and change their content without asking an agent or editing code. Have an administrator review any custom script and test interactions before publication. The definition and tool sequence below are references for your agent or for manual API work; you do not need to enter them by hand. ## Alternative: create it in the portal 1. Select the Site and open **Blocks**. Create a block type and choose a starter such as an icon list, feature cards or numbered steps. 2. Give it a machine name and a clear label. Define the fields editors should change, rather than exposing the entire layout as HTML. 3. Adapt its composition, or use **Turn into block type…** on an existing section in the page editor and select which values become fields. 4. Use **Preview** with realistic text, empty optional fields and long values. Check the available narrow and wide preview sizes. Resolve validation errors. 5. Save the type, return to a Page and add it from the block library. Edit its fields, save the Page and preview it in context before publishing. ## Example: an editable advice callout This definition exposes a heading and a paragraph. The heading remains an H2; editors do not need to rebuild the design. It can be passed directly to `create_block_type`, or to `POST /api/v1/sites/{siteId}/block-types`. ```json { "name": "advice_callout", "label": "Advice callout", "category": "content", "schema": [ { "name": "heading", "type": "text", "label": "Heading", "required": true }, { "name": "message", "type": "text", "label": "Advice", "required": true } ], "composition": [ { "id": "callout", "type": "core/container", "data": { "direction": "column", "gap": "sm", "css_class": "advice-callout" }, "children": [ { "id": "heading", "type": "core/heading", "data": { "text": "{{props.heading}}", "level": "h2" } }, { "id": "message", "type": "core/text", "data": { "text": "{{props.message}}" } } ] } ], "styles": ".advice-callout { border-inline-start: 4px solid var(--color-primary); padding: 1.25rem; }" } ``` A binding such as `{{props.heading}}` connects an editor field to an inner block. Whole-value bindings preserve types: arrays remain arrays and booleans remain booleans. Use `core/text` for plain field values and `core/prose` for rich text. ### Validate, preview, then save 1. Call `list_block_types` and `read_block_type` for the blocks you will use. `list_block_type_starters` returns complete definitions you can adapt. 2. Call `validate_block_type` with the definition under `definition`. Errors include paths such as `/schema/0/name`; fix them before continuing. 3. Call `preview_block_type` with the same `definition` and sample `data: { "heading": "Before you begin", "message": "Measure the doorway." }`. Inspect the returned `document` visually. Try long and missing values too. 4. Call `create_block_type` with the definition’s top-level properties. Use the returned `block_type.id` when placing an instance. 5. Call `add_block` for the intended Page, using: ```json { "page_id": "YOUR_PAGE_ID", "block": { "type": "advice_callout", "data": { "heading": "Before you begin", "message": "Measure the doorway." } } } ``` Read the Page again, save its working copy and preview before deployment. For a site version, pass the same `version` to all supported tools. ## When you need custom HTML Use the same fields, but replace `composition` with `template`: ```html ``` `{{heading}}` is escaped text; the surrounding section omits its markup when empty. Rich-text fields can use triple braces. Repeating groups use `{{#each items}}`; link fields support a helper that avoids empty links. See the [full field and template syntax](https://typeroll.com/docs/tools/custom-block-types/). CSS is scoped to the block. Prefer the site’s variables and [named styles](https://typeroll.com/docs/tools/styles/) so the component follows the site’s design. Custom markup is sanitized; putting a script tag in it does not enable JavaScript. A separate `script` property is executable code and needs deliberate code review. The unsaved block preview does not execute scripts, so verify interactions in an appropriate test deployment as well. See the [script permission rules](https://typeroll.com/docs/tools/blocks/parts/#site-block-types). ## Maintain and share the type Changing the definition affects every instance at the next deployment. Before an update, inspect **Usage** or call `find_pages_using_block_type`. Rename fields with the supported `renames` mapping so stored values follow the change; do not silently remove and recreate fields. Removing populated fields or changing their type can require explicit data-loss confirmation. Export and import `.tcblocks` packages to reuse a type on another Site. Review imported HTML, CSS and scripts before accepting them. Deleting a type in use is blocked; replace its instances first. For a new type, an AI agent can propose its schema, composition and responsive behavior from your brief, then validate it and show a preview. Inspect existing uses before changing a shared definition. See [Personal AI connections](https://typeroll.com/docs/guides/ai-connections/). ## Check it `validate_block_type` reports no errors for the definition, and `preview_block_type` renders it with sample data at the widths you support. Before changing a type that is already in use, `find_pages_using_block_type` lists the Pages to review.