GrowSitedevelopers

Text and headings

From schema to text editing, typography and persistence.

What you are building

An editable heading and description block. Customers can change its text, color, alignment and heading size. The complete blocks/text.html file appears below and in the example package. Copy it into your package, allow text in the parent, then rebuild the catalog.

1. Declare the content fields

Use a text setting for the heading and textarea for the description. id is the storage key, label is the editor label and default is the actual initial value. A placeholder is not a default value.

json
[
  {"type":"text","id":"title","label":"Heading","default":"Meet us"},
  {"type":"textarea","id":"text","label":"Description","default":"Tell your story."}
]

Recognized IDs such as title, text and label integrate with the shared text editor. Other IDs remain editable through schema controls; do not assume every arbitrary ID supports inline editing.

2. Bind content to markup

html
<h2 data-text-field="[[ block.settings_path ]].title" gs-text="block.settings.title"></h2>
<p data-text-field="[[ block.settings_path ]].text" gs-text="block.settings.text"></p>

The expression inside the tag displays the value. data-text-field tells the editor where to save it. Both must point to the same setting. Sections use section.settings and section.settings_path; blocks use block. Never hardcode instance IDs such as first.

Choose heading levels by document structure: the page title is an h1, sections use h2, subsections use h3. Adjust visual size through CSS or a setting rather than choosing a heading level for its appearance.

3. Add appearance controls

Use color for text color, range with unit: "px" for size and select for alignment. The example has a 20–64 px range with a 32 px default. Store a number, then append px when rendering.

html
<h2 style="font-size:[[ block.settings.heading_size ]]px;color:[[ block.settings.color ]]" data-text-field="[[ block.settings_path ]].title" gs-text="block.settings.title"></h2>

The multiline description uses .launch-copy-body { white-space: pre-line; } to preserve ordinary line breaks. Rich text editing stores a separate formatting document in content.canvas.fields; do not manually put HTML in the plain text value.

4. Make the block available

The parent needs "blocks":[{"type":"text"}] or that entry alongside its other allowed types. The block needs a preset and the parent needs <template gs-slot="blocks"></template>. After importing, add it in the builder. A file alone does not place it in the picker.

Static and dynamic text

Put fixed interface strings in locale dictionaries and render them with t. Declare customer content as settings. Read site.name directly or connect a text setting to a dynamic source.

An empty string is a valid saved value. Avoid adding a default filter that restores text the customer intentionally removed. Plain text containing markup is escaped.

Code blocks and inline code

A theme must style rich-text code as well as headings and paragraphs. The renderer uses .rich-text pre for a code block and .rich-text code for code, including inline fragments. Add these rules to an assets/*.css file in the theme package. Use a monospace font, preserve line breaks, and scroll long lines inside the code block instead of widening the page.

This example uses GrowSite Skeleton's .sk-page wrapper and --sk-* color variables. Replace them with your own theme wrapper and tokens when reusing it:

css
.sk-page .rich-text pre {
  max-width: 100%;
  overflow-x: auto;
  padding: 24px;
  border: 1px solid var(--sk-border);
  border-top: 3px solid var(--sk-accent);
  border-radius: 16px;
  background: var(--sk-surface);
  color: var(--sk-text);
  font: 14px/1.75 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  white-space: pre;
  overflow-wrap: normal;
}
.sk-page .rich-text code {
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--sk-surface);
  color: var(--sk-accent);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.sk-page .rich-text pre code {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
}

GrowSite Skeleton ships this styling in assets/blog.css, alongside its Blog and Comments styles. Its selectors also cover rich text outside the blog when rendered inside .sk-page. The complete implementation is in the Skeleton download.

Test inline code, multiline blocks, long lines and mobile widths. Ensure code nested inside pre does not receive a second background or padding. These rules style code presentation; they do not add syntax highlighting or execute code.

Verify the finished element

Click the preview text, edit and save it. Then edit through schema to check stale rich text does not hide the new value. Test empty text, accented characters, a long word, multiple paragraphs, both size limits and mobile. Reload the builder and compare public rendering.

Complete block file

blocks/text.html

html
<div class="launch-copy" style="color:[[ block.settings.color ]];text-align:[[ block.settings.alignment ]]">
  <h2 data-text-field="[[ block.settings_path ]].title" style="font-size:[[ block.settings.heading_size ]]px" gs-text="block.settings.title"></h2>
  <p class="launch-copy-body" data-text-field="[[ block.settings_path ]].text" gs-text="block.settings.text"></p>
</div>
Download Markdown copy
Results · 22
GS Loom UI components

Shared components, variants and theme styling.

Font catalog

Available fonts, previews and font declarations in GS Loom.

Menus and navigation

Create menus, connect links and style navigation.

Blog and comments

Blog and comments

SEO and plugin contracts

SEO and plugin contracts

Build your first theme

A complete package, installation and your first edit.

GS Loom Playground

Test themes locally without an API, database or upload.

Architecture and files

How author files become a customer website.

Schema and settings

Control types, default values and stable identifiers.

Blocks, targeting and order

Definitions, instances, nesting and static blocks.

Preview editing

Connect text, cards, images and icons to the builder.

Text and headings

From schema to text editing, typography and persistence.

Buttons and links

Labels, destinations, colors, dimensions and accessible states.

Inputs and form fields

Field types, labels, options, limits and validation.

Forms step by step

Instances, site binding, submission and error handling.

Cards, icons, images and badges

Container appearance, icon sizes and media editing.

Dynamic sources

Site data, page context and fallback values.

Layouts and shared settings

Section groups, global configuration and page templates.

Languages and translations

Starter languages, customer-added languages and AI translations.

Snippets, CSS and assets

Reusable markup, responsive styling and safe URLs.

Testing, import and updates

Validate a package and release it while preserving customer data.

Capabilities and limits

The supported GS Loom contract and working with AI.