resend/resend-laravel
Laravel integration for Resend with a facade and Symfony Mailer transport. Configure your RESEND_API_KEY, send via Resend::emails()->send(), or use the bundled Laravel mailer by setting transport=resend and MAIL_MAILER=resend.
composer require resend/resend-laravel
.env:
RESEND_API_KEY=re_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
use Resend\Laravel\Facades\Resend;
Resend::emails()->send([
'from' => 'acme@resend.dev',
'to' => 'user@example.com',
'subject' => 'Welcome!',
'html' => '<p>Hello!</p>',
]);
Replace Laravel's default mailer in config/mail.php:
'default' => env('MAIL_MAILER', 'resend'),
'resend' => [
'transport' => 'resend',
],
Set MAIL_MAILER=resend in .env and use Laravel's Mailable classes as usual:
Mail::to('user@example.com')->send(new WelcomeMail());
Direct API Calls Use the facade for non-Mailable emails:
Resend::emails()->send([
'from' => 'noreply@acme.com',
'to' => ['user1@example.com', 'user2@example.com'],
'subject' => 'Monthly Report',
'html' => view('emails.report')->render(),
'attachments' => [
['filename' => 'report.pdf', 'content' => file_get_contents('path/to/report.pdf')],
],
]);
Mailable Integration
Extend Laravel's Mailable class:
class WelcomeMail extends Mailable {
public function build() {
return $this->subject('Welcome!')
->markdown('emails.welcome')
->with(['name' => 'John'])
->attach('path/to/file.pdf');
}
}
Webhook Handling
Register the middleware in app/Http/Kernel.php:
protected $middleware = [
// ...
\Resend\Laravel\Http\Middleware\VerifyWebhookSignature::class,
];
Handle events in a controller:
public function handleWebhook(Request $request) {
$event = $request->resend_event;
if ($event->type === 'email.delivered') {
// Update database
}
}
Idempotency Keys Prevent duplicate sends:
Resend::emails()->send([
// ... email data ...
'idempotency_key' => 'unique-key-123',
]);
Tags & Metadata Categorize emails for analytics:
Resend::emails()->send([
// ... email data ...
'tags' => ['newsletter', 'welcome'],
'metadata' => ['user_id' => 123],
]);
Inline Attachments Embed images in HTML:
$email = Resend::emails()->send([
'from' => 'acme@resend.dev',
'to' => 'user@example.com',
'html' => '<img src="cid:logo">',
'attachments' => [
['content_id' => 'logo', 'content' => file_get_contents('logo.png')],
],
]);
API Key Validation
RESEND_API_KEY is set and valid. Test with:
Resend::api()->verifyApiKey();
Resend\Exceptions\ApiKeyInvalidException if invalid.Attachment Headers
Content-Disposition) may be stripped. Use the attach() method in Mailable:
$this->attach('file.pdf', [
'as' => 'custom-name.pdf',
'mime' => 'application/pdf',
]);
Webhook Signatures
VerifyWebhookSignature middleware to validate Resend's signatures.$request->resend_signature; // Check raw signature
$request->resend_timestamp; // Verify timestamp
Rate Limits
Resend\Exceptions\RateLimitException gracefully:
try {
Resend::emails()->send([...]);
} catch (\Resend\Exceptions\RateLimitException $e) {
Log::warning('Rate limited. Retrying in 60s...');
sleep(60);
retry();
}
Enable Verbose Logging
Add to config/resend.php:
'debug' => env('RESEND_DEBUG', false),
Logs API requests/responses to storage/logs/resend.log.
Inspect Sent Emails
Use the sent method to fetch recent emails:
$emails = Resend::emails()->sent()->get();
dd($emails[0]->id); // Debug email ID
Test Webhooks Locally Use ngrok to expose a local endpoint:
ngrok http 8000
Configure Resend webhook URL to https://your-ngrok-url.ngrok.io/webhook.
Custom Transport
Extend ResendTransport for custom logic:
class CustomResendTransport extends \Resend\Laravel\Transport\ResendTransport {
public function send(SentMessage $message) {
// Modify payload before sending
$payload = $this->preparePayload($message);
$payload['custom_field'] = 'value';
return parent::send($message);
}
}
Bind in AppServiceProvider:
Mail::extend('custom_resend', function () {
return new CustomResendTransport();
});
Event Listeners
Listen for Resend events (e.g., email.sent):
Resend::emails()->sent(function ($email) {
// Log or process sent email
});
Configuration Publishing Publish the config for customization:
php artisan vendor:publish --provider="Resend\Laravel\ResendServiceProvider" --tag="resend-config"
Modify config/resend.php to override defaults (e.g., API endpoint).
How can I help you explore Laravel packages today?