Enviando Emails em HTML no Laravel: Tutorial de SMTP e API

On maio 22, 2024
17min read
Ivan Djuric, an author at Mailtrap
Ivan Djuric Technical Content Writer @Mailtrap

Neste guia passo a passo sobre como enviar emails em HTML no Laravel, vou mostrar como enviar emails em HTML no Laravel usando tanto um servidor SMTP quanto uma API de email. Além disso, mostrarei como personalizar o HTML de um Mailable e criar conteúdo dinâmico.

Eu também usei o Mailtrap como uma solução de Email Sending. Além disso, antes de enviar emails, você deve usar o Email Testing, mencionado na documentação oficial do Laravel.

Para pular direto para a configuração do SMTP clique aqui, ou para a configuração da API, clique aqui.

Nota: os processos e trechos de código que forneço neste artigo são compatíveis com Laravel 9.x e superior.

Configurando o serviço de email do Laravel e mailables

Antes de começarmos a enviar emails no Laravel, primeiro precisamos configurar o próprio projeto, gerar e, em seguida, personalizar os mailables.

Gerando e escrevendo mailables

Para configurar os serviços de email no Laravel, usaremos o arquivo de configuração config/mail.php. Ele tem uma seção mailers, que contém um exemplo de configuração para cada um dos principais drivers/transports de email suportados pelo Laravel.

O valor de configuração padrão no arquivo config/mail.php determina quais mailers usaremos, por padrão, ao enviar emails do nosso aplicativo Laravel. Isso dá-nos flexibilidade, pois a configuração permite escolher diferentes serviços de email para diferentes tipos de emails.

Para representar diferentes tipos de emails, o Laravel usa uma classe mailable, que é armazenada no diretório app/Mail por padrão. Mas, lembre-se de que você não verá isso no seu projeto desde o início, pois será gerado quando você criar seu primeiro mailable.

Para criar uma classe mailable, use o seguinte comando Artisan:

php artisan make:mail MailableName

Após criar uma classe mailable, você pode usar os métodos da tabela abaixo para ver seu conteúdo e configurar a classe:

MétodoExplicação
EnvelopeRetorna o objeto Illuminate\Mail\Mailables\Envelope, que define o assunto e os destinatários.
ContentRetorna o objeto Illuminate\Mail\Mailables\Content, que define o Blade template usado para gerar o conteúdo da mensagem.
AttachmentsRetorna um array de anexos.

Configuração do remetente

Você pode especificar o remetente ou o endereço de email e nome do from em:

  • O objeto Envelope da mensagem
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Envelope;
 
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
{
   return new Envelope(
       from: new Address('example@example.com', 'Test Sender'),
       subject: 'Test Email',
   );
}
  • O arquivo config/mail.php
'from' => ['address' => 'example@example.com', 'name' => 'App Name']

Nota: Recomendo usar o endereço global from se você planeja usá-lo em todos os emails que sua aplicação envia. Isso pode ser bastante conveniente, pois evita a necessidade de chamar o método from em cada uma das suas classes mailable. Além disso, servirá como o endereço from padrão se você não especificar nenhum outro.

Personalizar o layout do Mailable

Para emails renderizados com Markdown, você pode criar seus próprios temas para mailables publicando os assets do laravel-mail e adicionando seus próprios arquivos CSS à pasta resources/views/vendor/mail/html/themes.

Aqui está o comando que você pode usar para publicar os assets:

php artisan vendor:publish --tag=laravel-mail

Este comando Artisan copia os templates HTML padrão de email do framework do Laravel para o diretório resources/views/vendor/mail da sua aplicação, permitindo que você os modifique conforme necessário.

Uma vez que você tenha seu tema pronto, você pode especificá-lo no Mailable com $theme = ‘customStyle’;

Lembre-se de que esta personalização é para emails renderizados com Markdown, que o Laravel então converte para HTML, aplicando o tema CSS especificado.

Configurar e personalizar templates Blade

Para criar conteúdo HTML dinâmico para nossos emails, o Laravel nos permite usar o Blade, um mecanismo de templates.

Primeiro, crie uma view Blade para seu email, que conterá a estrutura HTML do seu email.

Por exemplo, vamos criar um arquivo chamado myHtmlEmail.blade.php no diretório resources/views/emails:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <style>
        p {
            font-size: 12px;
        }

        .signature {
            font-style: italic;
        }
    </style>
</head>
<body>
<div>
    <p>Oi {{ $name }},</p>
    <p>Seu app Laravel já consegue enviar emails em HTML? 😉 </p>
    <p class="signature">Mailtrap</p>
</div>
</body>
</html>

Os templates Blade permitem que você escreva seus emails HTML e os personalize com tabelas, estilos e outros elementos HTML.

Por exemplo, você pode fazer o arquivo incluir o nome do destinatário usando o atributo with para passá-lo. Aqui está como:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    private $name;

    /**
     * Criar uma nova instância de mensagem.
     *
     * @param string $name
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * Construir a mensagem.
     *
     * @return $this
     */
    public function build()
    {
        return $this->subject('My Test Email')
                    ->view('emails.myHtmlEmail')
                    ->with([
                        'name' => $this->name,
                    ]);
    }
}

Este código garante que a view myHtmlEmail.blade.php seja corretamente referenciada na classe Mailable.

Dicas adicionais de personalização:

  • Para estilização CSS, você pode incluir tags <style> dentro da seção <head> do seu template Blade HTML. 
  • Você pode modificar diretamente os arquivos Blade e CSS se publicar os templates do vendor com o seguinte comando:
    • php artisan vendor:publish --tag=laravel-mail
  • Embora você possa vincular arquivos CSS externos, lembre-se de que muitos provedores de email não suportam folhas de estilo externas.
  • Ao usar dados dinâmicos nos emails, certifique-se de que qualquer conteúdo gerado pelo usuário esteja protegido contra ataques de cross-site scripting (XSS). A sintaxe do Blade do Laravel atinge isso escapando automaticamente o output com {{ }}, mas seja cauteloso de qualquer forma.

Enviar emails em HTML usando SMTP

Agora, vamos ao Mailtrap Email Sending e use o SMTP como um provedor de serviços no seu aplicativo/projeto, crie classes mailable e veja se tudo funciona.

Passo 1. Integrar o servidor SMTP do Mailtrap com seu app

Primeiro, precisamos inserir as credenciais do servidor SMTP fornecidas pelo Mailtrap Email Sending no arquivo .env do nosso aplicativo web.

Então, crie uma conta Mailtrap, faça login e navegue até Sending Domains, onde você precisará adicionar e verificar seu domínio.

Após verificar seu domínio, você será levado à página de onde pode copiar as credenciais SMTP. Dependendo dos tipos de mensagens de email que você deseja enviar, escolha um stream (Transactional ou Bulk) e cole as credenciais em seu aplicativo ou serviço de envio de email.

Aqui está como suas credenciais de email SMTP devem se parecer quando coladas no arquivo .env:

// .env file

MAIL_MAILER=smtp
MAIL_HOST=live.smtp.mailtrap.io
MAIL_PORT=587
MAIL_USERNAME=//seu username
MAIL_PASSWORD=//sua password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=from@example.com
MAIL_FROM_NAME=//nome do seu app

Passo 2. Criar classes mailable

Para criar classes mailable que mencionei anteriormente, use o seguinte comando:

php artisan make:mail MyTestEmail

Depois de executar este comando, você deve ver a classe MyTestEmail em “app/mailMyTestEmail.php”. Claro, você pode nomeá-la como desejar, pois MyTestEmail é apenas um exemplo.

E aqui está o código da classe:

<?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;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Criar uma nova instância de mensagem.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Obter o envelope da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */

    public function envelope()
    {
        return new Envelope(
            subject: 'My Test Email',
        );
    }
 /**
     * Get the message content definition.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */

    public function content()
    {
        return new Content(
            view: 'view.name',
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem
     *
     * @return array
     */
    public function attachments()
    {
        return [];
    }
}

E finalmente, vamos criar uma rota no arquivo routes/web.php com o seguinte código:

<?php

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;
use Illuminate\Support\Facades\Mail;

Route::get('/testroute', function() {
    $name = "Funny Coder";

    // O envio de email é feito usando o método to na fachada Mail
    Mail::to('testreceiver@gmail.com')->send(new MyTestEmail($name));
});

E aqui está como o arquivo deve ficar no final:

Para testar as coisas, você pode executar o comando php artisan serve e ir para o seu navegador onde você colou a rota criada. Por exemplo, no meu caso, foi localhost:8000/testroute.

Se tudo estiver funcionando como deveria, seu email deve chegar na caixa de entrada do endereço “to” que você especificou anteriormente.

Observe que com este código, seu email HTML terá a aparência padrão. Para personalizá-lo ainda mais, clique aqui.

Enviar emails em HTML com imagem incorporada

O Laravel nos permite incorporar imagens diretamente nos emails, exibindo-as inline, em vez de anexá-las como ficheiros separados. Isso pode ser muito útil para logos, ícones ou outros elementos que você pode adicionar para tornar o design do seu email único.

Para incorporar imagens no Laravel, usaremos novamente o template Blade, mais especificamente o embed method. Com este método, podemos anexar imagens diretamente e elas serão exibidas inline.

Vamos supor que você tem uma imagem em public/images/logo.png. Para adicioná-la, basta adicionar a seguinte linha de código ao seu template Blade:

<img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">

Esta linha essencialmente incorpora a imagem localizada em public/images/logo.png no seu email, e o método embed retorna uma URL que aponta para a imagem. A imagem retornada é então usada como o atributo src da tag <img>, exibindo a imagem inline no email.

Aqui está como o código do seu template Blade deve se parecer:

// resources/views/mail/test-email.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div>
        <p>Oi {{$name}},</p>
        <p>Seu app Laravel já consegue enviar emails? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">
    </div>
</body>
</html>

Enviando emails em HTML com anexos

Para enviar emails em HTML com anexos, você pode modificar o método attachments no código que usámos anteriormente.

Confira:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Contracts\Queue\ShouldQueue;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Criar uma nova instância de mensagem.
     *
     * @return void
     */
    public function __construct(private $name, public $attachedFile){ }

    /**
     * Obter o envelope da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'My Test Email',
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obter os anexos da mensagem.
     *
     * @return array
     */
    public function attachments()
    {
        return [
            Attachment::fromPath($this->attachedFile),
        ];

    }
}

Você também precisa fazer alterações no código testroute em routes/web.php:

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;
use Illuminate\Support\Facades\Mail; // Ensure Mail facade is imported

Route::get('/testroute', function () {
    $filePath = public_path('favicon.ico');
    $name = "Funny Coder";

    // Corrigido o erro de sintaxe no endereço de email
    Mail::to('testreceiver@gmail.com')->send(new MyTestEmail($name, $filePath));
});

Se você usar este código, seus emails devem vir com um anexo ICO chamado favicon.ico, conforme visto no bloco de código acima.

Como enviar emails em HTML para vários destinatários

Para enviar emails em HTML para vários destinatários, você pode usar este código:

foreach (['First Coder' => 'first-recipient@gmail.com', 'Second Coder' => 'second-recipient@gmail.com'] as $name => $recipient) {
    Mail::to($recipient)->send(new MyTestEmail($name));
}

Basicamente, este código itera sobre um array de destinatários, criando a instância mailable de  cada vez. Isso evita o envio de outro email para cada destinatário anterior a cada iteração ao longo do loop.

Você também pode enviar emails para apenas um destinatário e para outros cc e bcc, com o seguinte exemplo de classe MyTest Email:

return new Envelope(
    subject: 'My Test Email',
    cc: ['testreceiver-cc@gmail.com'],
    bcc: ['testreceiver-bcc@gmail.com']
);

Enviando emails em HTML com conteúdo dinâmico

Para enviar emails em HTML com conteúdo dinâmico, você pode usar:

  • Uma classe Mailable

Basta definir sua view e dados na classe Mailable que criamos anteriormente:

// app/Mail/MyTestEmail.php
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    public $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    public function build()
    {
        return $this->view('emails.welcome')
                    ->with(['name' => $this->name])
                    ->from('me@gmail.com')
                    ->subject('Welcome!');
    }
}
  • O método ‘mail::send()’

Se você não quiser usar a classe Mailable, pode usar diretamente o método mail::send(), assim:

use Illuminate\Support\Facades\Mail;

Mail::send('emails.welcome', ['name' => 'Charles'], function ($message) {
    $message->to('example@gmail.com')
            ->from('me@gmail.com', 'Seu Nome ou Nome do Seu Aplicativo')
            ->subject('Welcome!');
});

Como estilizar emails em HTML

Para estilizar seu email HTML, você pode simplesmente escrever código HTML estático no arquivo de template resources/views/emails/test-email.blade.php.

Para isso, use o seguinte código:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tema Belíssimo</title>
<style>


body {
    font-family: 'Arial', sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f4f4f4;
  }


  .container {
    max-width: 800px;
    margin: auto;
    padding: 20px;
    background-color: white;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
  }
  button {
    background-color: #008CBA; /* Blue */
    border: none;
    color: white;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    margin: 4px 2px;
    cursor: pointer;
  }


  button:hover {
    background-color: #005f73;
  }
</style>
</head>
<body>


<header>
  <h1>Bem-vindo à Minha Página com um Belo Tema! {{$name}}</h1>
</header>


<div class="container">
  <p>Este é um exemplo de uma página HTML com um belo tema, usando apenas estilos inline para seu layout e design.</p>
  <button>Clique em mim!</button>
</div>


</body>
</html>

Pro Tip

  • Se você quiser enviar emails em HTML, incorpore tudo na própria mensagem de email. Links externos que chamam automaticamente o servidor principal para carregar recursos adicionais são algo que os filtros de spam não gostam.
  • Eu não recomendo usar bibliotecas CSS externas para estilização, pois alguns clientes de email provavelmente bloquearão links externos. Portanto, seu email pode não aparecer como deveria.

Enviar emails em HTML usando API

Para automatizar seu processo de envio, você pode integrar a API de email do Mailtrap ao seu aplicativo Laravel usando o SDK PHP oficial e a documentação para a bridge com o framework Laravel.

A biblioteca Mailtrap é totalmente compatível com Laravel 9.x e superior e, o mais importante, a integração é super fácil.

Tudo o que você precisa fazer é:

  • Registrar-se com uma conta Mailtrap
  • Adicionar e verificar seu domínio.
  • Instalar o cliente PHP Mailtrap e dependências com Composer.
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7
  • Adicionar o transport Mailtrap ao seu arquivo config/mail.php.
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Configurações de Mailer
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // iniciar transporte mailtrap
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // finalizar o transporte mailtrap
    
    ]
];
  • Adicionar suas credenciais do Mailtrap ao seu arquivo .env do Laravel (escolha stream Transactional ou Bulk dependendo das suas necessidades)
MAIL_MAILER="mailtrap"
MAILTRAP_HOST="send.api.mailtrap.io"
MAILTRAP_API_KEY="SUA_API_KEY_AQUI"
MAIL_FROM_ADDRESS="name@registered_domain.com"
  • Criar uma classe mailable para enviar emails.
php artisan make:mail WelcomeMail
  • Configurar a classe app/Mail/WelcomeMail.php, assim:
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Attachment;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Headers;
use Illuminate\Queue\SerializesModels;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;

    private string $name;

    /**
     * Criar uma nova instância de mensagem.
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * Obter o envelope da mensagem.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address('jeffrey@example.com', 'Jeffrey Way'),
            replyTo: [
                      new Address('taylor@example.com', 'Taylor Otwell'),
                  ],
            subject: 'Welcome Mail',
            using: [
                      function (Email $email) {
                          // Cabeçalhos
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'example.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

                          // Variáveis Personalizadas
                          $email->getHeaders()
                              ->add(new CustomVariableHeader('user_id', '45982'))
                              ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
                          ;

                          // Categoria (deve ser apenas uma)
                          $email->getHeaders()
                              ->add(new CategoryHeader('Integration Test'))
                          ;
                      },
                  ]
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem.
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obter os anexos da mensagem.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [
           Attachment::fromPath('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg')
                ->as('logo.svg')
                ->withMime('image/svg+xml'),
        ];
    }

    /**
     * Obter os cabeçalhos da mensagem.
     */
    public function headers(): Headers
    {
        return new Headers(
            'custom-message-id@example.com',
            ['previous-message@example.com'],
            [
                'X-Custom-Header' => 'Custom Value',
            ],
        );
    }
}
  • Criar um template de email em resources/views/mail/welcome-email.blade.php.
Oi, {{$name}} e bem-vindo 😉

<br>
Funny Coder
  • Adicionar o roteador CLI ao arquivo app/routes/console.php.
<?php

use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Mail;

/*
|--------------------------------------------------------------------------
| Rotas de Console
|--------------------------------------------------------------------------
|
*/

Artisan::command('send-welcome-mail', function () {
    Mail::to('testreceiver@gmail.com')->send(new WelcomeMail("Jon"));
    // Além disso, você pode usar um mailer específico se o seu mailer padrão não for "mailtrap" mas você quiser usá-lo para emails de boas-vindas
    // Mail::mailer('mailtrap')->to('testreceiver@gmail.com')->send(new WelcomeMail("Jon"));
})->purpose('Send welcome mail');
  • Envie seu email de teste chamando o comando CLI.
php artisan send-welcome-mail

E estamos prontos! Após seguir estes passos, você deve ser capaz de enviar emails através da API de email do Mailtrap sem obter nenhum erro.

Enviar emails em HTML com imagem incorporada

Para adicionar imagens embutidas aos seus emails em HTML, você pode usar o embed method no template Blade.

Vamos supor que você deseja adicionar uma imagem de public/images/logo.php. Aqui está como o código ficaria nesse caso:

// resources/views/mail/test-email.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div>
        <p>Oi {{$name}},</p>
        <p>Seu app Laravel já consegue enviar emails? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">
    </div>
</body>
</html>

Enviando emails em HTML com anexos

Assim como enviar emails em HTML com anexos via SMTP, você pode modificar o método attachments para adicionar anexos aos seus emails HTML se estiver usando uma API.

Primeiro, vamos ajustar a classe MyTestEmail:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Contracts\Queue\ShouldQueue;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Criar uma nova instância de mensagem.
     *
     * @return void
     */
    public function __construct(private $name, public $attachedFile){ }

    /**
     * Obter o envelope da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'My Test Email',
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obter os anexos da mensagem.
     *
     * @return array
     */
    public function attachments()
    {
        return [
            Attachment::fromPath($this->attachedFile),
        ];

    }
}

Então, vamos mudar o código testroute em routes/web.php, assim:

<?php

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;

Route::get('/testroute', function () {

    $filePath = public_path('favicon.ico');

    $name = "Funny Coder";

    Mail::to('testreceiver@gmail.com')->send(new MyTestEmail($name, $filePath));
});

Novamente, se você seguiu tudo corretamente, seu email deve chegar com um anexo ICO chamado favicon.ico.

Como enviar emails em HTML para vários destinatários

Para enviar emails em HTML para vários destinatários, use o código a seguir:

foreach (['First Coder' => 'first-recipient@gmail.com', 'Second Coder' => 'second-recipient@gmail.com'] as $name => $recipient) {
    Mail::to($recipient)->send(new MyTestEmail($name));
}

Ou adicione mais destinatários em cc e bcc ao enviar um email para uma pessoa, adicionando o seguinte código à classe MyTestEmail:

return new Envelope(
    subject: 'My Test Email',
    cc: ['testreceiver-cc@gmail.com'],
    bcc: ['testreceiver-bcc@gmail.com']
);

Enviando emails em HTML com conteúdo dinâmico

Enviar emails em HTML com conteúdo dinâmico via API é similar ao envio via SMTP.

Você pode fazer isso com uma classe Mailable definindo sua view e dados nela, assim:

// app/Mail/MyTestEmail.php
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    public $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    public function build()
    {
        return $this->view('emails.welcome')
                    ->with(['name' => $this->name])
                    ->from('me@gmail.com')
                    ->subject('Welcome!');
    }
}

Ou você pode usar o método mail::send:

use Illuminate\Support\Facades\Mail;

Mail::send('emails.welcome', ['name' => 'Charles'], function ($message) {
    $message->to('example@gmail.com')
            ->from('me@gmail.com')
            ->subject('Bemvindo!');
});

Teste os emails antes de enviar

Depois de escrever todo esse código, é de extrema importância testar seus emails no Laravel antes de enviá-los.

Para começar, enviando sem testar, você não sabe se seus emails HTML estão sendo renderizados corretamente por certos navegadores da web. Além disso, eles podem estar sendo marcados como spam, e tudo isso sem você saber.

Felizmente, você pode usar o Mailtrap Email Testing, que é parte da Plataforma Mailtrap Email Delivery e é suportado pelo Laravel na documentação oficial.

Com o Email Testing, você pode visualizar suas mensagens em um ambiente sandbox seguro e analisar seu HTML/CSS antes de enviá-las. Isso permite corrigir/remover qualquer código defeituoso que você encontrar, para que seus emails HTML cheguem impecáveis nas caixas de entrada dos seus destinatários, independentemente do navegador ou dispositivo que possam estar usando.

Além disso, o Email Testing também fornece um Relatório de Spam – um recurso que informa a pontuação de spam dos seus emails. Se você mantiver essa pontuação abaixo de 5, evita uma quantidade significativa dos possíveis problemas de entregabilidade de emails quando seu aplicativo avançar para produção.

Testar emails com o Mailtrap é super fácil de qualquer forma, e todo o processo leva cerca de 5 minutos para configurar.

SMTP

Para começar, você precisa criar uma conta gratuita no Mailtrap, com a qual você terá acesso a toda a Plataforma Mailtrap Email Delivery. Isso significa que você poderá usar tanto o Email Testing quanto o Email Sending.

Depois de fazer login na sua conta, basta seguir estes passos simples:

  • Navegue até Email Testing → Inboxes → SMTP Settings
  • Escolha a versão do Laravel que você está usando (recomendo a versão 9+)
  • Copie/cole o snippet de código gerado no arquivo .env, que deve se parecer com isso:
MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=07f4dbf61b8122
MAIL_PASSWORD=d7fc5d57bc6eac
MAIL_ENCRYPTION=tls

Depois de terminar, você pode usar este código para enviar seu primeiro email de teste:

<?php
use App\Mail\JustTesting;
use Illuminate\Support\Facades\Mail;
Route::get('/send-mail', function () {
    Mail::to('newuser@example.com')->send(new JustTesting());
    return 'A message has been sent to Mailtrap!';
});

API

Se você quiser integrar o Email Testing no seu app para testes, para automação e para testar sequências automatizadas, aqui está o que você deve fazer:

  • Execute um dos seguintes comandos (dependendo do cliente HTTP que você usa):
# Com o cliente http symfony (recomendado)
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7

# Ou com o cliente http guzzle
composer require railsware/mailtrap-php guzzlehttp/guzzle php-http/guzzle7-adapter
  • Adicione o transporte Mailtrap ao seu arquivo config/mail.php:
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Configurações de Mailer
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // início do transporte mailtrap
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // fim do transporte mailtrap
    
    ]
]
  • Insira sua chave API na variável <strong>MAILTRAP_API_KEY</strong> e defina seu ID de caixa de entrada para MAILTRAP_INBOX_ID
    • Para encontrar sua chave API/token, navegue até Sending Domains → SMTP/API Settings
MAIL_MAILER="mailtrap"

MAILTRAP_HOST="sandbox.api.mailtrap.io"
MAILTRAP_API_KEY="SUA_API_KEY_AQUI"
MAILTRAP_INBOX_ID=1000001
  • Execute o seguinte comando de limpeza do cache de configuração para configurar novas variáveis:
php artisan config:clear
php artisan make:mail WelcomeMail
  • Configure seu email; por exemplo:
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Attachment;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Headers;
use Illuminate\Queue\SerializesModels;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;

    private string $name;

    /**
     * Criar uma nova instância de mensagem.
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * Obter o envelope da mensagem.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address('jeffrey@example.com', 'Jeffrey Way'),
            replyTo: [
                      new Address('taylor@example.com', 'Taylor Otwell'),
                  ],
            subject: 'Email de Boasvindas',
            using: [
                      function (Email $email) {
                          // Cabeçalhos
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'example.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

                          // Variáveis Personalizadas
                          $email->getHeaders()
                              ->add(new CustomVariableHeader('user_id', '45982'))
                              ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
                          ;

                          // Categoria (deve ser apenas uma)
                          $email->getHeaders()
                              ->add(new CategoryHeader('Integration Test'))
                          ;
                      },
                  ]
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obter os anexos da mensagem.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [
           Attachment::fromPath('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg')
                ->as('logo.svg')
                ->withMime('image/svg+xml'),
        ];
    }

    /**
     * Obter os cabeçalhos da mensagem.
     */
    public function headers(): Headers
    {
        return new Headers(
            'custom-message-id@example.com',
            ['previous-message@example.com'],
            [
                'X-Custom-Header' => 'Custom Value',
            ],
        );
    }
}
  • Use um template de email (opcional):
# resources/views/mail/welcome-email.blade.php

Oi, {{$name}} e bem-vindo 😉

<br>
Funny Coder
  • Adicionar router CLI:
# app/routes/console.php
<?php

use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Mail;

/*
|--------------------------------------------------------------------------
| Rotas de Console
|--------------------------------------------------------------------------
|
*/

Artisan::command('send-welcome-mail', function () {
    Mail::to('testreceiver@gmail.com')->send(new WelcomeMail("Jon"));
    // Além disso, você pode usar um mailer específico se o seu mailer padrão não for "mailtrap" mas você quiser usá-lo para emails de boas-vindas
    // Mail::mailer('mailtrap')->to('testreceiver@gmail.com')->send(new WelcomeMail("Jon"));
})->purpose('Send welcome mail');
  • Envie seu email de teste com o seguinte comando CLI:
php artisan send-welcome-mail

Procurando informações adicionais? Certifique-se de ler a documentação oficial da API do Mailtrap!

Concluíndo

E é isso! Chegamos ao fim do nosso guia sobre como enviar emails em HTML no Laravel.

Espero que agora você tenha uma melhor compreensão deste framework PHP tão popular e que possa começar a enviar seus emails imediatamente, tanto via SMTP quanto API.

Se quiser expandir ainda mais seus conhecimentos, sinta-se à vontade para consultar nossos outros artigos dedicados ao Laravel, como:

Ivan Djuric, an author at Mailtrap
Article by Ivan Djuric Technical Content Writer @Mailtrap

I’m a Technical Content Writer with 5 years of background covering email-related topics in tight collaboration with software engineers and email marketers. I just love to research and share actionable insights with you about email sending, testing, deliverability improvements, and more. Happy to be your guide in the world of emails!