Laravel 10 comes with some changes in sending emails and writing mailable, here we will cover that with an example that can work with most cases like sending attachments.
First of all, you need to add your email credentials to the .env file, the configuration may be different from one provider to another but the below is just an example.
MAIL_MAILER=smtp
MAIL_HOST=example.com
MAIL_PORT=26
MAIL_USERNAME=test@example.com
MAIL_PASSWORD="YOUR PASSWORD"
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=test@example.com
MAIL_FROM_NAME="${APP_NAME}"
You can add more than one email in the mailers array in config\mail.php
'mailers' => [
'smtp' => [
'transport' => 'smtp',
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'timeout' => null,
'local_domain' => env('MAIL_EHLO_DOMAIN'),
],
'ses' => [
'transport' => 'ses',
],
'mailgun' => [
'transport' => 'mailgun',
],
Useful tutorials
- How to Generate PDF Files in Laravel That Support RTL Languages.
- How To Make ZIP Files From Multiple Directories in Laravel.
Create Email
We are ready to create our first email service in Laravel 10 project.
php artisan make:mail GeneralEmail
The command created a mailable class app\Mail\GeneralEmail.php
we are going to modify the code in the class to look like that.
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Address;
class GeneralEmail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct(
public string $fromAddress,
public string $fromName,
public string $theSubject,
public string $theMessage,
public string $recipientName,
)
{
//
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
from: new Address($this->fromAddress, $this->fromName),
subject: $this->theSubject,
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
markdown: 'emails.general_email',
with:[
'recipientName'=>$this->recipientName,
'theMessage'=>$this->theMessage,
]
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}
The constructor will take the email for the “from address” and the name that should be on the email, besides the subject, Email message, and recipient name.
The envelope function for configuring the sender of the email. It takes the email “from address” and the subject.
The content method is for the body of the email, we can define the view, or which template should be used when rendering the email’s message. You can change “markdown” with “view” but we won’t take advantage of the pre-built templates and components of Laravel mail notifications of Markdown mailable messages.
Email View
Let’s create our view blade file “resources\views\emails\general_email.blade.php”, the design is simple but it got everything we need for now, we can greet the recipient and tell the message.
<x-mail::message>
<div >
Hello {{ $recipientName}},
<br><br>
</div>
<div >
{{$theMessage}}
</div>
Thanks,<br>
{{ config('app.name') }}
</x-mail::message>
If you want to add a button link with a URL here is the code below.
<x-mail::button :url="$url">
View Order
</x-mail::button>
Send Email
Now we have got everything ready to send the email in this route below using the Mail class to send our email.
use App\Mail\GeneralEmail;
use Illuminate\Support\Facades\Mail;
Route::get('/send-email',function(){
Mail::to( 'recipient@email.com')->send(
new GeneralEmail(
fromAddress:'test@example.com',
fromName:'ahmed',
theSubject:'test email',
theMessage:'welcome my man',
recipientName:'John',
)
);
return "mail sent!";
});
Attachments
Let’s send an attachment with our email, we will send a file from storage in this example it will be an image from “attachments” storage.
use Illuminate\Mail\Mailables\Attachment;
class GeneralEmail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct(
public string $fromAddress,
public string $fromName,
public string $theSubject,
public string $theMessage,
public string $recipientName,
public string $attachmentPath ="",
)
//...
//..
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
if($this->attachmentPath != ""){
return [
Attachment::fromPath($this->attachmentPath)
];
}
return [];
}
}
We called the mailable attachment class in the attachments method, the last function in our file. and we add $attachmentPath
as an optional parameter. If we give a file path it will send the email with attachment.
Let’s see how can we send the attachment
Route::get('/send-email',function(){
Mail::to( 'xxxxxxxxx@gmail.com')->send(
new GeneralEmail(
fromAddress:'test@example.com',
fromName:'ahmed',
theSubject:'test email',
theMessage:'welcome my man',
recipientName:'John',
attachmentPath: Storage::disk('attachments')->path('1/user.png')
)
);
return "mail sent!";
});
We get the file path from storage and pass it to attachmentPat
h. Now our mailing class is ready to be used anywhere in your application.
I hope that was useful for you.