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

Unlayer Filament Laravel Package

community-sdks/unlayer-filament

A Filament integration for Unlayer that lets you create, edit, and manage email templates with a drag-and-drop designer directly in your Laravel admin panel. Embed the Unlayer editor in Filament resources and streamline template management.

View on GitHub
Deep Wiki
Context7

Getting Started

v1.0.0 is the first tagged release of community-sdks/unlayer-filament, a Filament integration for the Unlayer email/landing-page editor. The release notes are only a changelog link, so treat the README and src/ as the source of truth for class names and options — this assessment describes the shape such a package takes and what to verify on day one.

Setup path:

composer require community-sdks/unlayer-filament
php artisan vendor:publish --tag="unlayer-filament-config"   # verify tag names in README
php artisan filament:assets                                  # if it ships compiled JS/CSS

Then, in a panel provider, either register the plugin:

public function panel(Panel $panel): Panel
{
    return $panel->plugin(\CommunitySdks\UnlayerFilament\UnlayerFilamentPlugin::make());
}

…or, if it's field-only, skip registration and use the field directly in a form schema.

Where to look first, in order: README.md → config/unlayer-filament.php (project ID, tools, appearance, storage settings) → resources/views/ (the Blade wrapper around the JS editor) → src/Fields/ (the Filament field class, its setUp() and state handling).

First use case: add the field to one form, store the raw Unlayer design JSON, and export HTML on save. That single loop — edit → persist JSON → render HTML → send — is the package's whole value proposition; validate it end-to-end before wiring it into more resources.

UnlayerEditor::make('design')
    ->label('Email body')
    ->columnSpanFull(),

Implementation Patterns

Two-column storage. Persist the design JSON and a rendered HTML snapshot separately. The JSON is the editable source of truth; the HTML is what you actually mail, so you never re-render at send time.

$table->json('design')->nullable();
$table->longText('html')->nullable();

Cast design to array in the model and let the field write the raw array. Render the HTML either via Unlayer's client-side export callback or your own Blade template that walks the design JSON — pick one and keep it consistent, because the two drift.

Form + preview action. Put the editor in the resource form and add a Action::make('preview') that renders the stored HTML inside an iframe (srcdoc) rather than injecting it into the panel DOM. Keep preview read-only so reviewers don't mutate state.

Sending. Treat the stored HTML as a Mailable body or pass it to your ESP. Merge tags ({{first_name}}) belong in the design, so replace them before handing off — decide whether substitution happens in PHP or at the provider.

Reusable subforms. Wrap the field in a small Livewire component or a Section you can reuse across templates, campaigns, and A/B variants. If the package exposes a standalone Livewire component, prefer that over duplicating resource forms.

Versioning. Designs are user-edited documents; snapshot them. A design_versions table with designable_id/designable_type and a created_at gives you rollback for free and makes support tickets tractable. Hook it into the model's updated event or a Filament afterSave.

Config over code. Set the Unlayer project ID and enabled tools in the published config rather than in the field call, so staging and production can differ. If the package supports per-field overrides, reserve those for genuinely per-form differences.

Gotchas and Tips

Pin the version. A 1.0.0 with a one-line changelog is a starting point, not a stability guarantee. Use "^1.0" and read each release before bumping; there's no migration history to infer the maintainers' breakage policy from yet.

Livewire state loss. JS editors wrapping a hidden input are the classic failure mode: re-render the component and the editor resets to empty. Confirm the field entangles correctly (wire:ignore on the editor container, explicit set() on change). Test with a validation error — that's when Filament re-renders and state disappears.

Asset pipeline. Filament assets are published, not served from vendor/. After every composer update, re-run php artisan filament:assets, and remember php artisan filament:optimize / optimize:clear in deploy scripts. A blank editor in production but not locally is almost always this.

CDN dependency. Unlayer loads its editor script from a CDN by default. That means CSP headers, air-gapped environments, and corporate proxies can all break it. Check whether the config offers a self-hosted script URL and set it if you have a strict CSP.

Payload size. Design JSON is verbose — a real email runs into hundreds of KB. Livewire ships it over the wire on every request in that component. Use ->dehydrated() deliberately, consider wire:model.defer-style behaviour on save, and don't put the editor on a page that also has a live-search table.

XSS. Stored HTML is user-authored and rendered raw. Sanitize on output (or render in a sandboxed iframe with a restrictive sandbox attribute) — an email builder is an HTML injection surface by design.

Column types. json on MySQL is fine; on older MySQL/MariaDB combinations and SQLite, longText with a cast is safer. Confirm the field emits an array, not a JSON string, before casting — a double-encode silently produces "\"{...}\"" and the editor loads empty.

Testing. assertFormSet/assertSchemaStateSet will exercise the state but not the JS. Anything about actual editing behaviour needs a browser test (Dusk/Pest browser) — budget for one smoke test rather than trying to unit-test the editor.

Extension points to inspect before forking: the Blade view (overridable via ->view()), the config file, and any registered custom tools. If the field class is final or the view is hard-coded, expect to copy the package into app/ for customisation — check this early, it changes your upgrade strategy.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core