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

Filament Mail Editor Laravel Package

jeffersongoncalves/filament-mail-editor

Filament Mail Editor adds a visual email template editor to Filament admin panels, letting you create, edit, and preview mail templates with a rich-text or code editor, Blade variable support, and seamless integration with Laravel mailables.

View on GitHub
Deep Wiki
Context7

Getting Started

This is now a two-package split. jeffersongoncalves/filament-mail-editor 1.1.0 is only the Filament layer (resources, drag-and-drop builder, metrics widget, block forms). All models, enums, events, support classes, config, migrations and translations live in jeffersongoncalves/laravel-mail-editor, which is pulled in automatically as a dependency.

  1. Install the plugin only — do not add laravel-mail-editor to your own composer.json unless you need to pin its version:
composer require jeffersongoncalves/filament-mail-editor
  1. Publish and run the core assets (note the mail-editor tag prefix, not filament-mail-editor):
php artisan vendor:publish --tag="mail-editor-migrations"
php artisan vendor:publish --tag="mail-editor-config"
php artisan vendor:publish --tag="mail-editor-translations"   # only if you override copy
php artisan migrate
  1. Read config/mail-editor.php first — it drives routes, models, mail/queue behaviour and the builder defaults. There is no config/filament-mail-editor.php any more.

  2. Register the plugin on the panel that should host the editor:

use JeffersonGoncalves\FilamentMailEditor\FilamentMailEditorPlugin;

public function panel(Panel $panel): Panel
{
    return $panel->plugin(FilamentMailEditorPlugin::make());
}
  1. First use case: open the mail template resource in the panel, create a template, drop blocks into the builder, hit Preview (served by the mail-editor.preview route), then wire the template to a mailable and send through your queue.

If you are coming from 1.0.x, treat this as a major upgrade despite the version number — see the migration checklist under Implementation Patterns.

Implementation Patterns

Upgrade checklist for 1.0 → 1.1. Do these in order; several failures are silent rather than fatal.

composer update jeffersongoncalves/filament-mail-editor -W
php artisan vendor:publish --tag="mail-editor-config"
php artisan migrate
php artisan optimize:clear     # config + route + view caches

Then grep your codebase for the four rename surfaces:

grep -rn "FilamentMailEditor" app/ config/ database/ resources/ routes/ tests/
grep -rn "filament-mail-editor" app/ config/ database/ resources/ routes/ tests/ lang/
grep -rn "filament-mail-editor-migrations\|filament-mail-editor-config" .
grep -rn "filament-mail-editor\." app/ resources/ routes/

Namespace migration. Every non-Filament class moved to the core namespace. The Filament layer (resources, builder, widget, block form components) stays in JeffersonGoncalves\FilamentMailEditor\….

1.0 1.1
JeffersonGoncalves\FilamentMailEditor\Models\* JeffersonGoncalves\MailEditor\Models\*
…\FilamentMailEditor\Enums\* …\MailEditor\Enums\*
…\FilamentMailEditor\Events\* …\MailEditor\Events\*
…\FilamentMailEditor\Support\* …\MailEditor\Support\*
…\FilamentMailEditor\Database\Seeders\* …\MailEditor\Database\Seeders\*

Keep a single use per model in your app and let IDE/rector handle the sweep — models referenced in relations, factories, policies, observers, $model overrides in config/mail-editor.php, and Filament resource $model properties all break together.

Config references. config('filament-mail-editor.x') now returns null without error. That is the most dangerous part of this release — a queue name or a disk silently becomes null and the editor still boots. Search for the string and replace with config('mail-editor.x'); add a boot-time assertion in your own service provider if this config is load-bearing:

abort_if(config('mail-editor.models.template') === null, 500, 'mail-editor config not published');

Routes. Preview and countdown now live at /mail-editor/preview and /mail-editor/countdown under the names mail-editor.preview / mail-editor.countdown. Use route() everywhere — any hardcoded /filament-mail-editor/... string, or a Blade url() copied into an email template, becomes a 404. Signed preview URLs minted before the deploy are invalidated by the path change, so treat any in-flight preview links as expired.

Translations. The language namespace moved with the rest of the core, so overrides that used to live under lang/vendor/filament-mail-editor are now orphaned. Re-publish with the mail-editor tag (same prefix pattern as config and migrations) and move any customised strings across — otherwise the UI silently reverts to package defaults. Keep label overrides out of the Filament layer; the core owns them now.

Custom blocks with a Filament form. Implement HasPropsSchema on your block class to get a real Filament form in the block library instead of a blind props editor:

use JeffersonGoncalves\MailEditor\Contracts\HasPropsSchema;

class CtaBlock implements HasPropsSchema
{
    public function getPropsSchema(): array
    {
        return [
            TextInput::make('label')->required(),
            TextInput::make('url')->url()->required(),
            Select::make('align')->options(['left' => 'Left', 'center' => 'Center']),
        ];
    }
}

Implement the contract from the core namespace — a class importing the old Filament-layer contract will not be recognised and the block silently falls back to raw props editing.

Import/export between environments. JSON exports now carry the mail-editor format id, and files exported with filament-mail-editor still import. That is one-way: a template exported from 1.1 cannot be re-imported into a 1.0 install. Keep the version of the receiving environment in mind when promoting templates from staging to production, and sequence the upgrade before importing anything.

Metrics widget. Register it on the panel alongside the plugin; it reads from the core models, so any custom $model overrides in config/mail-editor.php must be applied before the widget will show non-zero stats.

Testing. 1.1.0 ships smoke tests for every resource page and custom table action — mirror that shape in your own suite rather than testing the builder internals:

it('renders the template resource', function () {
    $this->actingAs(User::factory()->create())
        ->get(TemplateResource::getUrl('index'))
        ->assertSuccessful();
});

Add one assertion per route name you depend on so the next rename fails loudly:

expect(Route::has('mail-editor.preview'))->toBeTrue();

Gotchas and Tips

  • Both packages installed. If laravel-mail-editor was ever required explicitly at an older version, Composer may resolve a core version that predates the 1.1 Filament layer. Run composer why jeffersongoncalves/laravel-mail-editor and remove the direct requirement unless you're deliberately pinning.
  • Stale published config. A leftover config/filament-mail-editor.php does nothing but mislead the next developer. Delete it; the single source of truth is config/mail-editor.php.
  • Double-publishing migrations. Publishing mail-editor-migrations into a database/migrations folder that already contains the old filament-mail-editor migrations will attempt to re-create tables. Keep the published core migrations and drop the old files, or rely on the package's own migrations.
  • Silent null config. The config key rename is the single most likely cause of "the editor works but emails don't send / land on the wrong disk". Anywhere you read config('filament-mail-editor.*'), replace and re-test — there is no deprecation shim.
  • Orphaned translation overrides. Copies under lang/vendor/filament-mail-editor are no longer loaded. The editor will look untranslated with no error; re-publish or move the files to the mail-editor namespace.
  • Route cache. route:cache holds the old /filament-mail-editor/* paths until php artisan optimize:clear. Symptom: previews 404 in production only, works locally.
  • Preview and countdown are public routes. They are registered outside the panel prefix, so their auth posture can change relative to 1.0 — check config/mail-editor.php for the middleware stack and confirm whether signed URLs are required before exposing templates to untrusted traffic.
  • JSON downgrade. mail-editor format id is not readable by 1.0 installs. If you run a blue/green or canary deploy, hold imports until all nodes are on 1.1.
  • Contract mismatch. HasPropsSchema exists in the core package. An implements that resolves to a stale class name compiles but is ignored at runtime — no exception, just a missing form. Verify with php artisan about / composer show that the core version matches the Filament layer.
  • Extension points that survived: the Filament resource pages, block library/forms, the builder, and the metrics widget are still in the plugin — customising pages, table actions and the block picker works as before. Everything data-shaped (models, enums, events, seeders, config, routes, translations) now belongs to the core, so file new behaviour on that side of the boundary.
  • Seeder location moved. If your test suite calls the old seeder class, RefreshDatabase will fail before any assertion runs. It is now JeffersonGoncalves\MailEditor\Database\Seeders\….
  • Listen to core events. Event classes moved namespace; a listener registered against the old FQCN will silently never fire. Re-run php artisan event:list after the upgrade and confirm your mail-editor listeners appear.
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