Buttons and links
Labels, destinations, colors, dimensions and accessible states.
A button that navigates
Use an a element styled as a button when the action opens a page, email address or telephone number. A button type="submit" submits a form and is owned by the form component. Replacing it with a link removes submission and validation behavior.
The complete blocks/button.html below exposes label, destination, visibility, colors, border, radius, horizontal/vertical padding and text size. Every control has a real default and affects the rendered style.
1. Label and destination
<a href="[[ safe_url(block.settings.url) ]]">
<span data-text-field="[[ block.settings_path ]].label" gs-text="block.settings.label"></span>
</a>Declare a text setting named label and a url setting named url. safe_url validates the destination. Binding the span enables text editing. This example edits its destination and appearance through schema controls; an ordinary anchor does not automatically receive every specialized legacy button editor feature.
| Destination | URL value |
|---|---|
| Site page | /contact |
| Page section | /#contact — the target must have that ID |
| External website | https://example.com |
mailto:hello@example.com |
|
| Telephone | tel:+31201234567 |
https://wa.me/31201234567 |
Use an international WhatsApp number without a plus sign or spaces. URL-encode any message parameters. Do not use executable URL schemes or inline handlers. The schema url control accepts a complete address; the platform's composite link-type selector is a separate editing mechanism.
2. Appearance and dimensions
Use precise labels: border width, corner radius, vertical padding, horizontal padding and text size. Use a range with numeric input, unit and limits. Declare colors as color to use the shared picker.
{"type":"range","id":"padding_x","label":"Horizontal padding","min":8,"max":64,"step":1,"default":20,"unit":"px"}padding:12px 20px means 12 px at top/bottom and 20 px at the sides. Border width zero hides the border; radius zero produces square corners. Do not replace zero with a default using a truthiness check.
3. States and accessibility
Add inline-flex layout, centered content, readable contrast, a 44 px minimum height, hover and visible keyboard focus styles. Do not remove the focus outline without providing a replacement. Labels should describe the action, such as “Contact us”.
Links open in the same tab by default. If a new tab is intentional, use target="_blank" with rel="noopener noreferrer" and communicate that behavior. Ordinary navigation does not require click handlers.
4. Icons and visibility
The example intentionally has no icon. Add one only when it will actually render; do not represent an icon-free button with a default star. See cards and media for icon integration.
The show_link setting hides the whole element with a Loom condition. Deleting the block instance removes it. An empty URL is not a meaningful destination: configure one or disable the link.
Form submit buttons
ContactFormPlugin disables submission while busy and shows status below the button. The Paylio footer binds its submit text to content.badge. Do not use a mail link as a substitute for submission. Follow the forms guide.
Final checks
Verify persisted label and URL, each destination type, zero border/radius, long mobile text, keyboard access and focus. Test navigation on the public preview because edit mode may intercept clicks.
Complete block file
See GS Loom UI components for primary, secondary, outline, ghost, link and danger variants, sizes, theme tokens and editable settings.
blocks/button.html
<template gs-if="block.settings.show_link">
<a class="launch-cta" href="[[ safe_url(block.settings.url) ]]" style="background:[[ block.settings.background ]];color:[[ block.settings.color ]];border:[[ block.settings.border_width ]]px solid [[ block.settings.border_color ]];border-radius:[[ block.settings.radius ]]px;padding:[[ block.settings.padding_y ]]px [[ block.settings.padding_x ]]px;font-size:[[ block.settings.font_size ]]px">
<span data-text-field="[[ block.settings_path ]].label" gs-text="block.settings.label"></span>
</a>
</template>