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

Email Customization Bundle Laravel Package

rich-id/email-customization-bundle

A Symfony bundle for customizing outgoing emails, with configurable templates, layouts, and styling so applications can brand and tailor transactional messages without duplicating markup across mailers.

View on GitHub
Deep Wiki
Context7

Getting Started

This release is a platform-compatibility bump: PHP 8.0+ and Symfony 5.4 (the last LTS of the 5.x line). That tells you most of what you need before writing a line of code:

  1. Confirm you can run it. Your app must be on PHP ≥ 8.0 and on a Laravel version that ships Symfony 5.4 components (Laravel 8.x late releases and 9.x). Check with composer why symfony/console — if you're pinned to symfony/*:^6.0, this release won't install alongside your app without an alias or a conflict workaround.
  2. Install and inspect the surface area. composer require <vendor>/<package>:^0.2 then read the package's composer.json (require, extra.laravel.providers, extra.laravel.aliases) and its src/ tree. At 0.x, the public API is the classes actually referenced in the README — everything else is internal and may move.
  3. Let auto-discovery do its job, then publish config. If the service provider is registered via extra.laravel, you only need php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider" for config/migrations. Verify with php artisan about or php artisan config:show <package> that your published file is actually the one being read.
  4. First real use case: wire the package into a single, low-risk path — typically one console command, one queued job, or one controller action — and confirm it works end-to-end under your real cache/queue drivers rather than the sync/array defaults.

Before investing further, run the package's own test suite against your PHP version (vendor/bin/phpunit or pest) — a 0.2.0 release whose only changelog entry is a platform bump often means "compiles and installs," not "feature-complete."

Implementation Patterns

Treat the service container as the integration seam. Resolve the package's entry point from the container rather than instantiating it, so you can swap it in tests and decorate it without forking:

// In a service provider or your own thin wrapper
$this->app->bind(Contract::class, fn ($app) => $app->make(PackageManager::class));

Wrap, don't scatter. Put a single adapter class in app/Support/ that owns all calls into the package. When 0.3.0 renames something (likely, at this version), you change one file. This also gives you a place to normalise exceptions into your app's domain errors.

Feature-flag the rollout. Because you're on a 0.x dependency, gate the new behaviour behind a config key or Laravel Pennant feature so a rollback is a config change, not a deploy:

if (Feature::active('package-bridge')) { /* new path */ }

Console-first adoption. If the package bridges Symfony Console, the cheapest integration is a thin Artisan command that delegates. You get full Laravel scheduling, $this->output, and signal handling for free, and you avoid entangling web requests with a dependency that may churn.

Use PHP 8.0 idioms at the boundary only. Constructor promotion, named arguments, and the nullsafe operator are available now, but avoid them in any class that must remain mockable by older tooling (some mocking libraries and static analysers still stumble on promoted readonly-ish patterns). Keep the package's own types out of your public signatures.

Pin tightly in composer.json. "<vendor>/<package>": "0.2.*" — not ^0.2. Under semver-for-0.x, ^0.2 allows 0.2.x only, which is right, but be explicit so a composer update on another branch doesn't silently pull a 0.3 with breaking changes.

Queue and cache drivers matter. If the package performs IO, exercise it under Redis/database queue and a real cache store in staging before production. Symfony 5.4's contracts are more prescriptive about return types than 5.2's, and a driver that returns null where an interface says array will now throw rather than coerce.

Gotchas and Tips

  • PHP 8.0 is a floor, not a ceiling — but 8.1 may bite. Symfony 5.4 predates PHP 8.1's "return type will not be null" deprecations in some spots. If you develop on 8.1/8.2, expect Deprecated: Return type of ... should be compatible notices from vendored code. Silence them with error_reporting(E_ALL & ~E_DEPRECATED) in a local-only bootstrap, never in production.
  • The Symfony 5.4 vs 6.x split is the real trap. Laravel 9 supports both Symfony 5.4 and 6.x depending on the patch. If your composer.lock resolved to 6.x, this package's ^5.4 constraint will either conflict outright or force a downgrade of unrelated packages. Run composer update --dry-run <vendor>/<package> first and read the resolution output carefully.
  • No changelog beyond the version line is a red flag for hidden changes. Diff the tag against 0.1.x (git diff 0.1.0..0.2.0 -- src/ config/) before upgrading. "Compatibility release" frequently carries signature tightening — nullable parameters becoming non-nullable, void return types added, final keywords appearing — all of which are technically breaking under semver but invisible in the release notes.
  • Config caching swallows published config changes. After editing the published config file, php artisan config:clear. In deployments, make sure config:cache runs after vendor:publish in your build pipeline, otherwise the published defaults never reach the compiled config.
  • Auto-discovery only works when the package is a direct dependency. If it's pulled in transitively, extra.laravel is not honoured and you must register the provider manually in config/app.php. Check composer why <vendor>/<package> if the provider seems "missing."
  • Debugging extension points: the intended seams are almost always (a) the published config, (b) a container binding you can override after the package's provider registers (register yours later in config/app.php, or use $this->app->extend()), and (c) a published interface you can implement. Anything protected/private is not a seam — don't subclass into it.
  • Plan the exit now. Symfony 5.4's security support ends November 2025, which means this package's dependency line has a hard deadline. Note it in your upgrade backlog alongside the eventual move to Symfony 6/7 and a Laravel 10/11 baseline, so the whole stack moves together rather than the package becoming the blocker.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core