Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Statamic Button Box Laravel Package

rias/statamic-button-box

A Statamic addon that provides a Button Box fieldtype for building groups of configurable call-to-action buttons in the control panel. Editors can add button labels, links, and styling options, then reuse the button set across pages and templates for consistent CTAs.

View on GitHub
Deep Wiki
Context7

Getting Started

Install it like any Statamic addon — Composer only, no manual provider registration (Statamic discovers packages that declare extra.statamic in their composer.json):

composer require rias/statamic-button-box
php artisan optimize:clear

Confirm it loaded before you touch a blueprint:

php artisan about            # addons are listed here in recent Statamic versions
php artisan statamic:stache:clear

Where to look first. For a small addon like this, the README is usually a stub — the real documentation is two files:

  1. vendor/rias/statamic-button-box/src/Fieldtypes/*.php — tells you the fieldtype handle (probably button_box) and, more importantly, which config keys it reads (options, default, clearable, multiple, max_items, icon, color, …).
  2. vendor/rias/statamic-button-box/resources/js/components/fieldtypes/*.vue — tells you which of those keys actually change rendering in the CP. If a config key isn't referenced there, it does nothing.

First use case: replace a select on a page blueprint with something a client can scan at a glance.

# resources/blueprints/collections/pages/page.yaml
sections:
  main:
    fields:
      - handle: hero_layout
        field:
          type: button_box
          display: Hero layout
          instructions: Pick how the hero should look.
          default: split
          options:
            split: Split
            centered: Centered
            full: Full bleed

Then branch in Antlers:

{{ if hero_layout == 'split' }}
  {{ partial:heroes/split }}
{{ elseif hero_layout == 'centered' }}
  {{ partial:heroes/centered }}
{{ elseif hero_layout == 'full' }}
  {{ partial:heroes/full }}
{{ /if }}

That's the 90% case: the stored value is the option key, and your templates react to it exactly as they would to a select.

Implementation Patterns

Always use the key→label map form. The key is what lands in the content file; the label is CP decoration only. Never store labels.

Pair it with conditional visibility so the choice drives the rest of the form:

      - handle: hero_image
        field:
          type: assets
          container: main
          max_files: 1
          if:
            hero_layout: 'split'   # or a `show_when`-style condition depending on your Statamic version

Human-readable output. The raw value is the key. If the fieldtype registers an augmentation/label method you can often do {{ hero_layout:label }}; verify in the CP by dumping the augmented value. If it doesn't, keep a mapping close to the template:

{{# resources/views/partials/layout-label.antlers.html #}}
{{ if hero_layout == 'split' }}Split
{{ elseif hero_layout == 'centered' }}Centered
{{ else }}Full bleed
{{ /if }}

…or expose a translated label from a config file and use {{ trans:layouts.hero_layout.split }}.

Share option sets across blueprints with a fieldset, so the option list exists once:

# resources/fieldsets/common/hero_layout.yaml
title: Hero layout
fields:
  -
    handle: hero_layout
    field:
      type: button_box
      options:
        split: Split
        centered: Centered
        full: Full bleed
# in the page blueprint
import:
  - common/hero_layout

Inside Replicator / Grid / Bard sets. It works as a normal nested field, but resist it there: a button box inside a repeating set produces a wall of buttons. Keep button boxes for top-level, one-per-page decisions (layout, alignment, variant, theme), and use select inside repeaters.

Reading it in PHP / custom controllers:

$layout = $entry->get('hero_layout');            // 'split'
$label  = $entry->augmentedValue('hero_layout'); // augmented value, if the fieldtype supports label()

Rendering in Blade passed through from a controller or view composer:

@switch($entry->get('hero_layout'))
    @case('split')    @include('heroes.split')    @break
    @case('centered') @include('heroes.centered') @break
    @default          @include('heroes.full')
@endswitch

Defaults matter. Set default: in the blueprint so new entries aren't null-valued and your {{ if }} chain has a guaranteed starting point.

Gotchas and Tips

  • It's a 2-star package with zero dependents. That's not a reason to avoid it, but it is a reason to pin it (composer require rias/statamic-button-box:^1.0), commit your composer.lock, and accept that a Statamic major bump may strand you. If the only value you need is "radio buttons that look nice," the built-in radio fieldtype with inline: true, or a select plus CP extra_css, gets you there with zero third-party risk. Choose this addon when the visual option card (icons/images/colors) is genuinely the point.
  • "Unknown fieldtype button_box" almost always means the addon wasn't discovered, not that the field config is wrong. Check vendor/composer/installed.json for the package, confirm it declares extra.statamic, then php artisan statamic:stache:clear — blueprint changes are stache-cached and stale blueprints produce confusing fieldtype errors.
  • Stale CP assets. After installing or updating, clear caches and do a hard reload (Cmd/Ctrl+Shift+R). If the field renders as an empty box or a broken Vue component, the compiled assets didn't load. If a vendor:publish config tag exists (php artisan vendor:publish --tag=button-box), check what it publishes — some addons let you override the Vue component, but recompiling an addon's JS is fragile; prefer subclassing the PHP fieldtype or wrapping the output in your own partial.
  • Statamic 5/6 asset builds. Older addons ship Laravel Mix output; Statamic 5+ CP is Vite/Vue 3. Test the field in the CP on a staging environment before handing the blueprint to a client — a broken fieldtype is discoverable only by opening the publish form.
  • YAML key typing. options: { 1: 'One', 2: 'Two' } becomes integers, not strings, so hero_layout == '1' fails. Quote numeric keys ('1': One) or use word keys everywhere.
  • Empty value handling. {{ if hero_layout }} guards the case where the client never picked anything; without a default: and without that guard you'll render nothing.
  • API/GraphQL. Single-select exports as a plain string and just works. If the fieldtype supports multi-select, the value is an array — set the GraphQL type explicitly or the schema inference will complain.
  • Don't let the label leak into templates. The temptation is {{ hero_layout }} for display; you'll then be stuck when a client asks to rename "Split" to "Two column." Keep keys stable and map to labels at render time.
  • Accessibility in the CP is on you. If you use icons or color swatches as options, include the text label too — a client shouldn't have to hover to know what a button does, and color-only distinctions fail for colorblind users.
  • Extension point, if you need one: copy the fieldtype class into app/Fieldtypes/ and extend it rather than editing vendor/. You get project-specific behaviour (extra config, custom augmentation) that survives composer update.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings