ronald2wing / laravel-mailtrap
Laravel mail driver for sending emails through Mailtrap.io Email Sending Service API
Fund package maintenance!
ronald2wing
Installs: 54
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
pkg:composer/ronald2wing/laravel-mailtrap
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.0
- illuminate/mail: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- laravel/pint: ^1.25
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0|^11.5
Suggests
- ext-curl: Required for Guzzle HTTP client
- ext-json: Required for JSON processing
- ext-mbstring: Required for multibyte string handling
- ext-openssl: Required for SSL/TLS support
This package is auto-updated.
Last update: 2026-01-20 15:36:31 UTC
README
A Laravel mail driver for sending emails through the Mailtrap.io Email Sending Service API. Seamlessly integrate Laravel with Mailtrap's sending API while using Laravel's familiar mail API.
โจ Features
- Easy Setup: Simple configuration with Laravel's mail system
- Full API Support: Categories, attachments, CC/BCC, custom headers
- Laravel Compatible: Works with Laravel 10.x, 11.x, and 12.x
- Clean Codebase: Well-documented with comprehensive tests
- Robust Error Handling: Clear error messages and debugging
- Email Analytics: Mailtrap categories for tracking
- UTF-8 Support: Full international character support
- Customizable: Configurable API endpoints and HTTP client
- High Performance: Optimized payload construction and HTTP requests
- Comprehensive Testing: 27+ tests covering all features
๐ Requirements
- PHP 8.2 or higher
- Laravel 10.x, 11.x, or 12.x
- GuzzleHTTP 7.0 or higher
- Required PHP extensions: curl, json, mbstring, openssl (recommended)
๐ Quick Start
1. Install via Composer
composer require ronald2wing/laravel-mailtrap
The package uses Laravel's auto-discovery, so the service provider will be registered automatically.
2. Configure Environment Variables
Add the following to your .env file:
MAIL_MAILER=mailtrap MAILTRAP_TOKEN=your_mailtrap_api_token_here
3. Configure Services
Add the Mailtrap configuration to your config/services.php file:
'mailtrap' => [ 'token' => env('MAILTRAP_TOKEN', ''), // Optional: Custom API endpoint (for testing or custom deployments) // 'endpoint' => 'https://custom.api.mailtrap.io/api/send', // Optional: Guzzle HTTP client configuration // 'guzzle' => [ // 'timeout' => 30, // 'connect_timeout' => 10, // 'verify' => true, // ], ],
4. Configure Mail Settings
Update your config/mail.php file to use the Mailtrap transport:
'default' => env('MAIL_MAILER', 'mailtrap'), 'mailers' => [ 'mailtrap' => [ 'transport' => 'mailtrap', ], // ... other mailers (smtp, log, etc.) ],
๐ Obtaining Your Mailtrap API Token
- Log in to your Mailtrap account
- Navigate to your sending domain settings
- Go to the "API" or "Integration" section
- Copy your API token
- Add it to your
.envfile asMAILTRAP_TOKEN
๐ Usage
Basic Email Sending
use Illuminate\Support\Facades\Mail; // Send a basic email Mail::to('recipient@example.com') ->send(new WelcomeEmail()); // Send with multiple recipients Mail::to(['user1@example.com', 'user2@example.com']) ->cc('manager@example.com') ->bcc('admin@example.com') ->send(new AnnouncementEmail());
Using Mailable Classes
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class WelcomeEmail extends Mailable { use Queueable, SerializesModels; public function __construct(public User $user) { } public function build() { return $this->subject('Welcome to Our Service, ' . $this->user->name) ->view('emails.welcome') ->text('emails.welcome_plain') ->with(['user' => $this->user]); } }
Mailtrap Categories for Analytics
Mailtrap categories help you track email performance and analytics:
use Illuminate\Support\Facades\Mail; // Using send method with category header Mail::send('emails.welcome', $data, function ($message) { $message->to('user@example.com') ->subject('Welcome') ->header('X-Mailtrap-Category', 'welcome-emails'); }); // In a Mailable class class WelcomeEmail extends Mailable { public function build() { return $this->view('emails.welcome') ->header('X-Mailtrap-Category', 'welcome-emails'); } } // Multiple categories (comma-separated) Mail::send('emails.newsletter', $data, function ($message) { $message->to('subscriber@example.com') ->subject('Weekly Newsletter') ->header('X-Mailtrap-Category', 'newsletter,marketing,weekly'); });
Attachments
use Illuminate\Support\Facades\Mail; // Single attachment Mail::send('emails.invoice', $data, function ($message) { $message->to('customer@example.com') ->subject('Your Invoice') ->attach('/path/to/invoice.pdf', [ 'as' => 'invoice-2024.pdf', 'mime' => 'application/pdf', ]); }); // Multiple attachments Mail::send('emails.report', $data, function ($message) { $message->to('manager@example.com') ->subject('Monthly Report') ->attach('/path/to/report.pdf') ->attach('/path/to/data.xlsx') ->attach('/path/to/chart.png'); }); // Inline attachments (embedded images) Mail::send('emails.newsletter', $data, function ($message) { $message->to('subscriber@example.com') ->subject('Newsletter with Images') ->attach('/path/to/logo.png', [ 'as' => 'logo.png', 'mime' => 'image/png', ]); });
CC and BCC Recipients
use Illuminate\Support\Facades\Mail; // With CC and BCC Mail::send('emails.announcement', $data, function ($message) { $message->to('primary@example.com') ->cc(['cc1@example.com', 'cc2@example.com']) ->bcc(['bcc1@example.com', 'bcc2@example.com']) ->subject('Important Announcement'); }); // In Mailable class class TeamUpdateEmail extends Mailable { public function build() { return $this->view('emails.team-update') ->to('team@example.com') ->cc('manager@example.com') ->bcc('hr@example.com') ->subject('Team Update'); } }
Custom Headers and Reply-To
use Illuminate\Support\Facades\Mail; // Custom headers and reply-to Mail::send('emails.contact', $data, function ($message) { $message->to('support@example.com') ->replyTo('user@example.com', 'John Doe') ->header('X-Priority', '1') ->header('X-Custom-ID', '12345') ->header('X-Tracking-ID', 'TRACK-789') ->subject('Support Request'); }); // Priority headers for urgent emails Mail::send('emails.urgent', $data, function ($message) { $message->to('admin@example.com') ->header('X-Priority', '1') // High priority ->header('Importance', 'high') ->subject('URGENT: System Alert'); });
HTML and Text Emails
use Illuminate\Support\Facades\Mail; // HTML email with fallback text version Mail::send(['html' => 'emails.welcome', 'text' => 'emails.welcome_plain'], $data, function ($message) { $message->to('user@example.com') ->subject('Welcome Email'); }); // Mailable with both HTML and text views class WelcomeEmail extends Mailable { public function build() { return $this->subject('Welcome') ->view('emails.welcome') // HTML view ->text('emails.welcome_plain'); // Plain text view } }
โ๏ธ Advanced Configuration
Custom API Endpoint
For testing or custom deployments, you can specify a different API endpoint:
// In config/services.php 'mailtrap' => [ 'token' => env('MAILTRAP_TOKEN', ''), 'endpoint' => 'https://sandbox.api.mailtrap.io/api/send', ],
HTTP Client Configuration
Customize the Guzzle HTTP client for specific needs:
// In config/services.php 'mailtrap' => [ 'token' => env('MAILTRAP_TOKEN', ''), 'guzzle' => [ 'timeout' => 30, // Request timeout in seconds 'connect_timeout' => 10, // Connection timeout in seconds 'verify' => false, // Disable SSL verification (not recommended for production) 'proxy' => 'http://proxy.example.com:8080', // Use a proxy 'headers' => [ 'User-Agent' => 'MyApp/1.0', ], ], ],
Multiple Mailtrap Configurations
You can configure multiple Mailtrap accounts for different purposes:
// In config/services.php 'mailtrap' => [ 'default' => [ 'token' => env('MAILTRAP_TOKEN_DEFAULT', ''), ], 'marketing' => [ 'token' => env('MAILTRAP_TOKEN_MARKETING', ''), 'endpoint' => 'https://send.api.mailtrap.io/api/send', ], 'transactions' => [ 'token' => env('MAILTRAP_TOKEN_TRANSACTIONS', ''), 'guzzle' => [ 'timeout' => 60, // Longer timeout for transactional emails ], ], ],
Then use them in your mail configuration:
// In config/mail.php 'mailers' => [ 'mailtrap_default' => [ 'transport' => 'mailtrap', 'config' => 'mailtrap.default', ], 'mailtrap_marketing' => [ 'transport' => 'mailtrap', 'config' => 'mailtrap.marketing', ], 'mailtrap_transactions' => [ 'transport' => 'mailtrap', 'config' => 'mailtrap.transactions', ], ],
๐งช Testing
Testing in Your Application
When testing your application that uses this package:
// In your test Mail::fake(); // Perform actions that send emails $user->sendWelcomeEmail(); // Assert emails were sent Mail::assertSent(WelcomeEmail::class, function ($mail) use ($user) { return $mail->hasTo($user->email) && $mail->hasHeader('X-Mailtrap-Category', 'welcome-emails'); });
๐ง Troubleshooting
Common Issues
1. Missing API Token Error
InvalidArgumentException: Mailtrap API token is missing. Please configure it in config/services.php under the "mailtrap.token" key or set MAILTRAP_TOKEN in your .env file.
Solution: Ensure your .env file contains MAILTRAP_TOKEN=your_token_here and the token is correctly set in config/services.php.
2. SSL Certificate Verification Failed
GuzzleHttp\Exception\RequestException: cURL error 60: SSL certificate problem: unable to get local issuer certificate
Solution:
-
Update your CA certificates:
sudo update-ca-certificates -
Or temporarily disable SSL verification (not recommended for production):
'guzzle' => [ 'verify' => false, ],
3. Timeout Errors
GuzzleHttp\Exception\ConnectException: Connection timed out after 10000 milliseconds
Solution: Increase timeout settings:
'guzzle' => [ 'timeout' => 60, 'connect_timeout' => 30, ],
4. UTF-8 Character Issues
If you're experiencing issues with international characters:
Solution: Ensure your email content is UTF-8 encoded and your database/application uses UTF-8 charset.
Debugging
Enable detailed logging to debug email sending:
// In config/mail.php 'mailers' => [ 'mailtrap' => [ 'transport' => 'mailtrap', ], 'log' => [ 'transport' => 'log', 'channel' => env('MAIL_LOG_CHANNEL'), ], ],
Then switch to log driver temporarily:
MAIL_MAILER=log
๐ค Contributing
We welcome contributions! Please follow these steps:
1. Fork and Clone
git clone https://github.com/ronald2wing/laravel-mailtrap.git
cd laravel-mailtrap
composer install
2. Create a Feature Branch
git checkout -b feature/amazing-feature
3. Make Your Changes
Follow the existing code style and patterns:
- Use type hints for all method parameters and return types
- Add PHPDoc blocks for public/protected methods
- Follow PSR-12 coding standards
- Write tests for new functionality
4. Run Quality Checks
composer run check
5. Commit and Push
git commit -m 'Add amazing feature'
git push origin feature/amazing-feature
6. Open a Pull Request
Create a pull request with a clear description of your changes.
๐ Performance Tips
- Batch Processing: When sending multiple emails, consider using Laravel's queue system
- Connection Reuse: The HTTP client reuses connections by default
- Attachment Size: Compress large attachments before sending
- Caching: Cache email templates when possible
- Queue Workers: Use queue workers for better throughput
๐ Security Considerations
- API Token Security: Never commit API tokens to version control
- SSL Verification: Always enable SSL verification in production
- Input Validation: Validate all user inputs before including in emails
- Attachment Validation: Validate file types and sizes for attachments
- Rate Limiting: Implement rate limiting for email sending
๐ Monitoring and Analytics
Mailtrap Dashboard
Monitor your email performance in the Mailtrap dashboard:
- Delivery rates
- Open rates
- Click-through rates
- Bounce rates
- Spam complaints
Application Logging
// Log email sending events Mail::send('emails.welcome', $data, function ($message) { $message->to('user@example.com') ->subject('Welcome'); Log::info('Welcome email sent to user@example.com'); });
๐ Useful Links
- Packagist
- GitHub Repository
- Issue Tracker
- [Mailtrap Documentation](https://