Laravel Mailgun Multi: Automatic Domain Routing for Multi-Brand Applications

If your Laravel application sends emails from multiple domains — think multi-tenant SaaS, multi-brand e-commerce, or white-label platforms — you know the pain. Laravel's mail system assumes one Mailgun domain. Laravel Mailgun Multi makes multi-domain email routing automatic and invisible.

The Multi-Domain Problem

Imagine you run a SaaS platform that white-labels for clients:

  • hello@acme-shop.com — Client A's transactional emails
  • noreply@brandx.io — Client B's notifications
  • support@yourplatform.com — Your own platform emails

With vanilla Laravel, you'd need to:

  1. Manually swap Mailgun credentials before each send
  2. Build a custom transport that resolves domains
  3. Handle queue serialization of the correct credentials
  4. Manage credential rotation across all domains

Laravel Mailgun Multi handles all of this with zero code changes to your existing mail logic.

Zero Code Changes

That's not marketing speak. Your existing code works as-is:

// This just works — domain detected automatically
Mail::to('user@example.com')
    ->send(new WelcomeMail());
// From: hello@acme-shop.com → Mailgun credentials for acme-shop.com ✓

Mail::to('admin@example.com')
    ->send(new InvoiceMail());
// From: billing@brandx.io → Mailgun credentials for brandx.io ✓

The package inspects the from address, matches it to a configured domain, and swaps the Mailgun API credentials automatically.

Configuration

// config/mailgun-multi.php
return [
    'domains' => [
        'acme-shop.com' => [
            'secret' => env('MAILGUN_SECRET_ACME'),
            'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
        ],
        'brandx.io' => [
            'secret' => env('MAILGUN_SECRET_BRANDX'),
            'endpoint' => env('MAILGUN_ENDPOINT', 'api.eu.mailgun.net'),
        ],
    ],
    'fallback' => env('MAILGUN_DOMAIN'),
];

Queue Compatible

Queued emails maintain the correct domain context. Whether you dispatch immediately or queue for later, the right credentials are always used:

// Queued — still routes correctly
Mail::to($user)
    ->queue(new OrderConfirmation($order));

Custom Domain Resolvers

Need more complex routing logic? Register a custom resolver:

MailgunMulti::resolveUsing(function (string $fromAddress) {
    $domain = Str::after($fromAddress, '@');
    return Tenant::where('mail_domain', $domain)->first()?->mailgun_credentials;
});

Supported Laravel Versions

  • Laravel 10.x
  • Laravel 11.x
  • Laravel 12.x

The package has been tested with PHP 8.2 and 8.3, and works with both the Mailgun US and EU endpoints.

Get started with Laravel Mailgun Multi on GitHub.

View on GitHubStar the repo, explore the source code, and get started.
Go to Repository
Share this post
Back to Blog