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

Buildamic Laravel Package

handmadeweb/buildamic

Buildamic is a Laravel page-builder package for composing flexible, block-based content layouts. It provides reusable components, configurable fields, and a simple editor experience so developers can ship editable pages without reworking their app's structure.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and confirm the pairing first. Buildamic is a Statamic 3 addon, so lock your Statamic version before anything else:

    composer require handmadeweb/buildamic
    php artisan vendor:publish --provider="HandmadeWeb\Buildamic\ServiceProvider"
    

    Then immediately check composer show handmadeweb/buildamic against your statamic/cms constraint. With 11 stars and zero dependents, this is effectively a single-agency internal tool that escaped — treat compatibility as unverified until you've clicked through the Control Panel yourself.

  2. Read these three places before writing a line of template code.

    • config/buildamic.php (after publishing) — which fieldsets are exposed as blocks, and any rendering/recursion settings.
    • src/Fieldtypes/ — the Vue component and PHP fieldtype tell you exactly what shape gets saved (_type, _id, nested blocks) far faster than the README.
    • resources/views/ — any shipped Blade/Antlers partials show the author's intended render loop.
  3. First use case: a "Page Sections" tab on a single collection. Don't retrofit an entire site. Add the Buildamic field to one blueprint (e.g. pages), define two or three blocks as fieldsets (hero, text_image, cta), and render them on one template. That gives you a working vertical slice and exposes any CP/UI breakage within an hour instead of a sprint.

  4. Where to look when the CP misbehaves: open the browser console on the publish form. A broken builder UI is almost always a Vue asset mismatch, not a PHP error — the PHP side will happily save whatever the JS sends.

Implementation Patterns

Fieldset-as-block is the whole mental model. Each block type is a Statamic fieldset; Buildamic stores an ordered array of { _type, _id, ...fields }. So your resources/fieldsets/ directory becomes the component library, and blueprints just reference it.

Render with a one-partial-per-block convention. Keep the loop dumb and push logic into the partial:

{{ buildamic }}
  {{ if type == "hero" }}
    {{ partial:blocks/hero }}
  {{ elseif type == "text_image" }}
    {{ partial:blocks/text_image }}
  {{ /if }}
{{ /buildamic }}

Name partials to match the fieldset handle exactly and you can collapse that to {{ partial src="blocks/{type}" }} — which scales to dozens of blocks without touching the parent template again.

Wrap the loop once, reuse everywhere. Put the render loop in resources/views/partials/blocks.antlers.html and call it with a scope variable. Adding a fourth collection that uses page builder content then costs one blueprint field and zero template work.

Compose layout blocks for nesting. Sections → columns → content blocks is the pattern that keeps editors happy. Nesting a Buildamic field inside a block's fieldset works, but cap it at two levels; deep recursion makes both the CP and the render loop miserable to reason about.

Build block data programmatically for seeders and imports. Because the value is just an array, you can generate it in a migration or importer. Keep _type matching the fieldset handle and generate a stable _id per block so re-runs don't duplicate:

$blocks = collect($sections)->map(fn ($s) => [
    '_id'   => (string) Str::uuid(),
    '_type' => $s['type'],
    ...$s['data'],
])->all();

Keep templates presentational. If you find yourself doing lookups inside block partials (resolving entry IDs, formatting money), add a small presenter or a Blade component per block and pass it the augmented block. That's also the seam that lets you unit-test block rendering without booting Statamic's tag parser.

Reuse fieldsets across contexts. The same fieldset can back a Buildamic block and a plain Replicator set. Define shared field groups as nested fieldsets rather than copy-pasting fields — renaming a field in one place is the difference between a five-minute change and a content migration.

Gotchas and Tips

  • Pin the version, hard. "handmadeweb/buildamic": "dev-main#<commit-sha>" or an exact tag. With zero dependents there is no ecosystem pressure keeping releases stable; a composer update can move you onto an unreviewed commit. Better still, fork it into your VCS and require the fork.
  • Statamic 4/5 is a real risk. Statamic's CP moved to Vue 3 and changed the fieldtype asset pipeline. If the builder UI doesn't mount, that's why — and the fix is usually a fork-and-port of the Vue component, not a config tweak. Validate the CP on a staging install before committing to the package on a Statamic 4+ project.
  • Never rename fieldset handles. The handle is persisted inside every saved block as _type. Rename it and existing content silently renders nothing (or throws). Add a data migration that rewrites stored _type values, or keep a legacy alias in your render partial.
  • Augmentation is not automatic for nested data. Top-level blocks usually augment when accessed in Antlers, but nested Buildamic values and relationship fields often come back raw. Call ->augmented() / augment() explicitly and dump the type when a value looks like an ID instead of an object.
  • Watch the query count on relationship-heavy blocks. Twenty blocks each referencing an entry is twenty queries if augmentation resolves lazily. Eager-load collections of referenced IDs up front, and cache fully rendered block output ({{ cache }} or a response cache) for content that changes rarely.
  • Debug by dumping the raw value, not the loop. {{ buildamic | dump }} (or ray()) shows you the true stored shape — array vs. Value object, whether _type is present, whether the block saved at all. Nine times out of ten "the block doesn't render" is a missing or mismatched _type, not a template bug.
  • Empty-field blocks still render. A block whose fields are all blank produces an empty partial and stray wrapper markup. Guard the wrapper in the parent, not in every child partial: skip blocks where the augmented value is effectively empty.
  • Override views via the vendor path, not by editing the package. Publish/copy into resources/views/vendor/buildamic so your customizations survive composer update. Same for any JS: build your own asset if you need CP changes.
  • Statamic search won't index block content by default. If editors expect page-builder copy to be searchable, index it explicitly — either flatten blocks into the searchable field or add an indexer that walks the blocks and concatenates text values.
  • Extension points worth knowing: custom fieldtypes usable inside blocks (the builder is just a field), published config for restricting which fieldsets appear as blocks, and the fieldset registry itself — you can register block definitions from a package rather than the project, which is how you'd share a block library across client sites.
  • No test safety net. Assume there's no meaningful test suite downstream of you. Add a smoke test that boots the addon, saves a page with two block types via the API, and asserts the rendered output contains both — that single test catches most upgrade breakage.
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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package