Enviar Emails HTML en Laravel: SMTP y API Tutorial

On febrero 11, 2025
17min read
Ivan Djuric, an author at Mailtrap
Ivan Djuric Technical Content Writer @Mailtrap

En esta guía paso a paso sobre cómo enviar emails HTML en Laravel, le mostraré cómo enviar emails HTML usando tanto un servidor SMTP como una API de email. Además, le mostraré cómo personalizar el HTML de un Mailable y crear contenido dinámico.

También utilicé Mailtrap como solución de Email API/SMTP. Además, antes de enviar emails, debería usar su Email Testing, mencionado en la documentación oficial de Laravel.

Para ir directamente a la configuración SMTP [click aquí], o para la configuración de API, [click aquí].

Nota: Tenga en cuenta que los procesos y snippets de código que proporciono en este artículo son compatibles con Laravel 9.x. y versiones superiores.

¿Listo para enviar sus emails?
Pruebe Mailtrap Gratis

Configuración del servicio de email y mailables en Laravel

Antes de comenzar a enviar emails en Laravel, primero necesitamos configurar el proyecto en sí, generar y luego personalizar los mailables.

Generación y escritura de mailables

Para configurar los servicios de email en Laravel, usaremos el archivo de configuración config.mail.php. Tiene una sección mailers, que contiene una entrada de configuración de muestra para cada uno de los principales drivers/transportes de email compatibles con Laravel.

El valor de configuración predeterminado en el archivo config.mail.php determina qué mailers usaremos por defecto al enviar emails desde nuestra aplicación Laravel. Esto nos da flexibilidad ya que la configuración nos permite elegir diferentes servicios de email para diferentes tipos de emails.

Para representar diferentes tipos de email, Laravel utiliza una clase mailable, que se almacena en el directorio app/Mail por defecto. Pero tenga en cuenta que no lo verá en su proyecto desde el principio, ya que se generará cuando usted cree su primer mailable.

Para crear una clase mailable, use el siguiente comando Artisan:

php artisan make:mail MailableName

Una vez que haya creado una clase mailable, puede usar los métodos de la tabla a continuación para ver su contenido y configurar la clase en sí:

MétodoExplicación
EnvelopeDevuelve el objeto Illuminate\Mail\Mailables\Envelope, que define el asunto y los destinatarios.
ContentDevuelve el objeto Illuminate\Mail\Mailables\Content, que define la plantilla Blade utilizada para generar el contenido del mensaje.
AttachmentsDevuelve un array de adjuntos.

Configuración del remitente

Puede especificar la dirección de email y el nombre del remitente o from en cualquiera de estos:

  • El objeto Envelope del mensaje
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Envelope;
 
/**
* Obtener el envelope del mensaje.
*
* @return \Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
{
   return new Envelope(
       from: new Address('su_email@ejemplo.com', 'Remitente de Prueba'),
       subject: 'Email de Prueba',
   );
}
  • El archivo config/mail.php
'from' => ['address' => 'su_email@ejemplo.com', 'name' => 'Nombre de la App']

Nota: Le recomiendo usar la dirección from global si planea usarla en todos los emails que envíe su aplicación. Puede ser algo muy conveniente, ya que puede evitar que tenga que llamar al método from en cada una de sus clases mailable. Además, si usted no especifica ninguna otra, esa servirá como dirección from predeterminada.

Personalización del diseño del Mailable

Para emails renderizados con Markdown, puede crear sus propios temas para mailables publicando los assets de laravel-mail y agregando sus propios archivos CSS a la carpeta resources/views/vendor/mail/html/themes.

Aquí está el comando que puede usar para publicar los assets:

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

Este comando Artisan copia las plantillas HTML de email predeterminadas del framework de Laravel al directorio resources/views/vendor/mail de su aplicación, lo que le permite modificarlas según sea necesario.

Una vez que tenga su tema listo, puede especificarlo en el Mailable con public $theme = 'customStyle';

Tenga en cuenta que esta personalización es para emails que renderizados con Markdown, que Laravel luego convierte a HTML, aplicando el tema CSS especificado.

Configuración y personalización de plantillas Blade

Para crear contenido HTML dinámico para nuestros emails, Laravel nos permite usar Blade, un motor de plantillas.

Primero, cree una vista Blade para su email, que contendrá la estructura HTML de su email.

Por ejemplo, creemos un archivo llamado myHtmlEmail.blade.php en el directorio 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>Hola {{ $name }},</p>
    <p>¿Su aplicación Laravel ya puede enviar emails HTML? 😉 </p>
    <p class="signature">Mailtrap</p>
</div>
</body>
</html>

Las plantillas Blade le permiten escribir sus emails HTML y personalizarlos con tablas, estilos y otros elementos HTML.

Por ejemplo, puede hacer que el archivo incluya el nombre del destinatario usando el atributo with para pasarlo. Así es cómo:

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

    /**
     * Crear una nueva instancia del mensaje.
     *
     * @param string $name
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * Construir el mensaje.
     *
     * @return $this
     */
    public function build()
    {
        return $this->subject('Mi Email de Prueba')
                    ->view('emails.myHtmlEmail')
                    ->with([
                        'name' => $this->name,
                    ]);
    }
}

Este código asegura que la vista myHtmlEmail.blade.php esté correctamente referenciada en la clase Mailable.

Consejos adicionales de personalización:

  • Para el estilo CSS, puede incluir etiquetas <style> dentro de la sección <head> de su plantilla HTML Blade.
  • Puede modificar los archivos Blade y CSS directamente si publica las plantillas del proveedor con el siguiente comando:
    • php artisan vendor:publish --tag=laravel-mail
  • Aunque puede vincular hojas de estilo externas, tenga en cuenta que muchos clientes no admiten hojas de estilo externas.
  • Cuando use datos dinámicos dentro de los emails, asegúrese de que cualquier contenido generado por el usuario esté escapado para prevenir ataques de scripts entre sitios (XSS). La sintaxis de Blade logra esto al escapar automáticamente la salida con {{ }}, pero sea cauteloso de igual manera.

Enviar email HTML usando SMTP

Ahora, vamos a Email API/SMTP de Mailtrap y usemos el SMTP como proveedor de servicios en su aplicación/proyecto, creemos clases mailable y veamos si todo funciona.

Paso 1. Integrar el servidor SMTP de Mailtrap con su app

Primero, necesitamos insertar las credenciales del servidor SMTP proporcionadas por Email API/SMTP de Mailtrap en el archivo .env de nuestra aplicación web.

Así que cree una cuenta en Mailtrap, inicie sesión y navegue a Sending Domains, donde necesitará agregar y verificar su dominio.

Después de verificar su dominio, será llevado a la página desde donde puede copiar las credenciales SMTP. Dependiendo de los tipos de mensajes de email que quiera enviar, elija un stream (Transactional o Bulk) y pegue las credenciales en su aplicación o servicio de envío de emails.

Así es como deberían verse sus credenciales de email SMTP cuando las pegue en el archivo .env:

// .env file

MAIL_MAILER=smtp
MAIL_HOST=live.smtp.mailtrap.io
MAIL_PORT=587
MAIL_USERNAME=//su nombre de usuario
MAIL_PASSWORD=// su contraseña
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=su_email@ejemplo.com
MAIL_FROM_NAME=//nombre de su app

Paso 2. Crear clases mailable

Para crear las clases mailable de las que hablé anteriormente, use el siguiente comando:

php artisan make:mail MyTestEmail

Una vez que ejecute este comando, debería ver la clase MyTestEmail bajo “app/mailMyTestEmail.php“. Por supuesto, puede nombrarla como quiera, ya que MyTestEmail es solo un ejemplo.

Y aquí está el código de la clase:

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

    /**
     * Crear una nueva instancia del mensaje.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Obtener el envelope del mensaje.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */

    public function envelope()
    {
        return new Envelope(
            subject: 'Mi Email de Prueba',
        );
    }
 /**
     * Obtener la definición del contenido del mensaje.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */

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

    /**
     * Obtener los adjuntos para el mensaje.
     *
     * @return array
     */
    public function attachments()
    {
        return [];
    }
}

Y finalmente, vamos a crear una ruta en el archivo routes/web.php con el siguiente código:

<?php

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

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

    // The email sending is done using the to method on the Mail facade
    Mail::to('destinatario@gmail.com')->send(new MyTestEmail($name));
});

Así es como debería verse finalmente el archivo:

Para probar las cosas, puede ejecutar el comando php artisan serve e ir a su navegador donde pegó la ruta creada. Por ejemplo, en mi caso, fue localhost:8000/testroute.

Si todo está funcionando como debería, su email debería terminar en la bandeja de entrada de la dirección “to” que especificó anteriormente.

Tenga en cuenta que con este código, su email HTML tendrá el aspecto predeterminado. Para estilizarlo más, haga click aquí.

Enviar email HTML con una imagen incrustada

Laravel nos permite incrustar imágenes directamente en los emails, mostrándolas en línea, en lugar de adjuntarlas como archivos separados. Esto puede ser súper útil para logos, íconos u otros elementos que puede agregar para hacer único su diseño de email.

Para incrustar imágenes en Laravel, usaremos la plantilla Blade nuevamente, o más específicamente, el método embed en ella. Con este método, podemos adjuntar imágenes directamente y serán mostradas en línea.

Digamos que tiene una imagen en public/images/logo.png. Para agregarla, simplemente añada la siguiente línea de código a su plantilla Blade:

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

Esta línea básicamente incrusta la imagen ubicada en public/images/logo.png en su email, y el método embed devuelve una URL que apunta a la imagen. La imagen devuelta se usa luego como el atributo src de la etiqueta <img>, mostrando la imagen en línea en el email.

Así es como debería verse el código de su plantilla Blade:

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

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div>
        <p>Hola {{$name}},</p>
        <p>¿Su aplicación Laravel ya puede enviar emails? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">
    </div>
</body>
</html>

Enviar emails HTML con archivos adjuntos

Para enviar emails HTML con archivos adjuntos, puede modificar el método attachments en el código que usamos anteriormente.

Échele un vistazo:

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

    /**
     * Crear una nueva instancia del mensaje.
     *
     * @return void
     */
    public function __construct(private $name, public $attachedFile){ }

    /**
     * Obtener el envelope del mensaje.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'Mi Email de Prueba',
        );
    }

    /**
     * Obtener la definición del contenido del mensaje.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obtener los adjuntos para el mensaje.
     *
     * @return array
     */
    public function attachments()
    {
        return [
            Attachment::fromPath($this->attachedFile),
        ];

    }
}

También necesita hacer cambios en el código testroute bajo routes/web.php:

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;
use Illuminate\Support\Facades\Mail; // Asegúrese de importar la fachada Mail

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

    // Sintaxis corregida en la dirección de email
    Mail::to('destinatario@gmail.com')->send(new MyTestEmail($name, $filePath));
});

Si usa este código, sus emails deberían venir con un adjunto ICO llamado favicon.ico, como se ve en el bloque de código anterior.

Cómo enviar emails HTML a múltiples destinatarios

Para enviar emails HTML a múltiples destinatarios, puede usar este código:

foreach (['Primer Programador' => 'primer-destinatario@gmail.com', 'Segundo Programador' => 'segundo-destinatario@gmail.com'] as $name => $recipient) {
    Mail::to($recipient)->send(new MyTestEmail($name));
}

Básicamente, este código se repite sobre un array de destinatarios, creando una instancia mailable cada vez. Esto evita el envío de otro email a cada destinatario anterior en cada iteración del bucle.

También puede enviar emails a un solo destinatario y poner cc y bcc a otros con el siguiente ejemplo de clase MyTestEmail:

return new Envelope(
    subject: 'Mi Email de Prueba',
    cc: ['destinatario-cc@gmail.com'],
    bcc: ['destinatario-bcc@gmail.com']
);

Enviar emails HTML con contenido dinámico

Para enviar emails HTML con contenido dinámico, puede usar:

  • Una clase Mailable

Simplemente defina su vista y datos en la clase Mailable que creamos 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('yo@gmail.com')
                    ->subject('¡Bienvenido!');
    }
}
  • El método ‘mail::send()’

Si no le apetece usar la clase Mailable, puede usar el método mail::send() directamente, así:

use Illuminate\Support\Facades\Mail;

Mail::send('emails.welcome', ['name' => 'Carlos'], function ($message) {
    $message->to('ejemplo@gmail.com')
            ->from('yo@gmail.com', 'Su Nombre o el Nombre de su Aplicación')
            ->subject('¡Bienvenido!');
});

Cómo estilizar el email HTML

Para estilizar su email HTML, puede simplemente escribir código HTML estático en el archivo de plantilla resources/views/emails/test-email.blade.php.

Para esto, puede usar el siguiente 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 Bonito</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>¡Bienvenido a Mi Página con un Bonito Tema! {{$name}}</h1>
</header>


<div class="container">
  <p>Este es solo un ejemplo de una página HTML con un tema bonito, usando solo estilos en línea para su diseño y maquetación.</p>
  <button>¡haga click aquí!</button>
</div>


</body>
</html>

Consejo Pro:

  • Si quiere enviar email HTML, incruste todo en el mensaje de email en sí. Los enlaces externos que automáticamente llaman al servidor de origen para cargar recursos adicionales son algo que a los filtros de spam no les gusta.
  • No recomiendo usar librerías CSS externas para estilizar ya que es probable que algunos clientes de email bloqueen los enlaces externos. Por lo tanto, su email puede no aparecer como debería.

Enviar email HTML usando API

Para automatizar su proceso de envío, puede integrar la API de email de Mailtrap en su aplicación Laravel usando el SDK oficial de PHP y la documentación para el bridge del framework Laravel.

La librería de Mailtrap es totalmente compatible con Laravel 9.x. y versiones superiores. Lo más importante es que la integración es super fácil.

Todo lo que tiene que hacer es:

  • Instalar el cliente PHP de Mailtrap y las dependencias con Composer.
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7
  • Agregar el transporte de Mailtrap en su archivo config.mail.php.
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Configuraciones del Mailer
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // inicio del transporte mailtrap
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // fin del transporte mailtrap
    
    ]
];
  • Agregar sus credenciales de Mailtrap a su archivo .env de Laravel (elija el stream Transactional o Bulk según sus necesidades)
MAIL_MAILER="mailtrap"
MAILTRAP_HOST="send.api.mailtrap.io"
MAILTRAP_API_KEY="SU_API_KEY_AQUÍ"
MAIL_FROM_ADDRESS="nombre@dominio_registrado.com"
  • Crear una clase mailable para enviar email.
php artisan make:mail WelcomeMail
  • Configure the app/Mail/WelcomeMail.php class, like so:
<?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;

    /**
     * Crear una nueva instancia del mensaje.
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * Obtener el envelope del mensaje.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address('jeffrey@ejemplo.com', 'Jeffrey Way'),
            replyTo: [
                      new Address('taylor@ejemplo.com', 'Taylor Otwell'),
                  ],
            subject: 'Email de Bienvenida',
            using: [
                      function (Email $email) {
                          // Encabezados
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'example.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

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

                          // Categoría (debe ser solo una)
                          $email->getHeaders()
                              ->add(new CategoryHeader('Prueba de Integración'))
                          ;
                      },
                  ]
        );
    }

    /**
     * Obtener la definición del contenido del mensaje.
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obtener los adjuntos para el mensaje.
     *
     * @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'),
        ];
    }

    /**
     * Obtener los encabezados del mensaje.
     */
    public function headers(): Headers
    {
        return new Headers(
            'custom-message-id@ejemplo.com',
            ['previous-message@ejemplo.com'],
            [
                'X-Custom-Header' => 'Custom Value',
            ],
        );
    }
}
  • Crear una plantilla de email bajo resources/views/mail/welcome-email.blade.php.
Hey, {{$name}} y bienvenido aquí 😉

<br>
Programador Divertido
  • Agregar el router CLI al archivo app/routes/console.php.
<?php

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

/*
|--------------------------------------------------------------------------
| Rutas de Consola
|--------------------------------------------------------------------------
|
*/

Artisan::command('send-welcome-mail', function () {
    Mail::to('destinatario@gmail.com')->send(new WelcomeMail("Jon"));
    // También puede usar un mailer específico si su mailer predeterminado no es "mailtrap" pero quiere usarlo para emails de bienvenida
    // Mail::mailer('mailtrap')->to('destinatario@gmail.com')->send(new WelcomeMail("Jon"));
})->purpose('Enviar email de bienvenida');
  • Enviar su email llamando al comando CLI.
php artisan send-welcome-mail

¡Y listo! Después de seguir estos pasos, debería poder enviar emails a través de la API de email de Mailtrap sin ningún error.

Enviar emails HTML con una imagen incrustada

Para agregar imágenes incrustadas a sus emails HTML, puede usar el método embed en la plantilla Blade.

Digamos que quiere agregar una imagen desde public/images/logo.php. Así es como se vería el código en ese caso:

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

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div>
        <p>Hola {{$name}},</p>
        <p>¿Su aplicación Laravel ya puede enviar emails? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">
    </div>
</body>
</html>

Enviar emails HTML con archivos adjuntos

Al igual que con el envío de emails HTML con adjuntos a través de SMTP, puede modificar el método attachments para agregar adjuntos a sus emails HTML si está usando una API.

En primer lugar, vamos a modificar la clase 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;

    /**
     * Crear una nueva instancia del mensaje.
     *
     * @return void
     */
    public function __construct(private $name, public $attachedFile){ }

    /**
     * Obtener el envelope del mensaje.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'Mi Email de Prueba',
        );
    }

    /**
     * Obtener la definición del contenido del mensaje.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obtener los adjuntos para el mensaje.
     *
     * @return array
     */
    public function attachments()
    {
        return [
            Attachment::fromPath($this->attachedFile),
        ];

    }
}

Luego, cambiamos el código testroute bajo routes/web.php, así:

<?php

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

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

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

    $name = "Programador Divertido";

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

Nuevamente, si siguió los pasos adecuadamente, su email debería llegar con un adjunto ICO llamado favicon.ico.

Cómo enviar emails HTML a múltiples destinatarios

Para enviar emails HTML a múltiples destinatarios, use el siguiente código:

foreach (['Primer Programador' => 'primer-destinatario@gmail.com', 'Segundo Programador' => 'segundo-destinatario@gmail.com'] as $name => $recipient) {
    Mail::to($recipient)->send(new MyTestEmail($name));
}

O, agregue más destinatarios en cc y bcc al enviar un email a una persona agregando el siguiente código a la clase MyTestEmail:

return new Envelope(
    subject: 'Mi Email de Prueba',
    cc: ['destinatario-cc@gmail.com'],
    bcc: ['destinatario-bcc@gmail.com']
);

Enviar emails HTML con contenido dinámico

Enviar emails HTML con contenido dinámico vía API es similar al envío SMTP.

Usted puede hacerlo con una clase Mailable definiendo su vista y datos en ella, así:

// 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('yo@gmail.com')
                    ->subject('¡Bienvenido!');
    }
}

O, puede usar el método mail::send:

use Illuminate\Support\Facades\Mail;

Mail::send('emails.welcome', ['name' => 'Carlos'], function ($message) {
    $message->to('ejemplo@gmail.com')
            ->from('yo@gmail.com')
            ->subject('¡Bienvenido!');
});

Probar emails antes de enviar

Una vez que haya escrito todos estos códigos, es de vital importancia probar sus emails en Laravel antes de enviarlos.

Para empezar, al enviar sin probar, no sabe si sus emails HTML están siendo renderizados correctamente por ciertos navegadores web. Además, podrían estar siendo marcados como spam, y todo esto sin que usted lo note.

Afortunadamente, puede usar Email Testing de Mailtrap, que es parte de la Plataforma de Email Delivery de Mailtrap y está soportada por Laravel en la documentación oficial.

Con Email Testing, puede previsualizar sus mensajes en un entorno sandbox seguro y analizar su HTML/CSS antes de enviarlos. Esto le permite arreglar/eliminar cualquier código defectuoso que encuentre, de esta manera sus emails HTML llegarán impecables a las bandejas de entrada de sus destinatarios, sin importar qué navegador o dispositivo estén usando.

Análisis HTML/CSS en Email Testing

Adicionalmente, Email Testing también le proporciona un Reporte de Spam, una característica que le indica el puntaje de spam de sus emails. Si mantiene este puntaje por debajo de 5, evita una porción significativa de potenciales problemas de entregabilidad de email una vez que su app pase a producción.

Probar emails con Mailtrap también es fácil, y todo el proceso toma menos de 5 minutos para configurar.

SMTP

Para empezar, tiene que crear una cuenta gratuita de Mailtrap, con la cual tendrá acceso a toda la Plataforma de Email Delivery de Mailtrap. Esto significa que podrá usar tanto Email Testing como Email API/SMTP.

Una vez que inicie sesión en su cuenta, solo siga estos simples pasos:

  • Navegue a Email Testing → Inboxes → SMTP Settings
  • Elija la versión de Laravel que está usando (recomiendo versión 9+)
Configuración SMTP de Laravel
  • Copie y pegue el snippet de código generado en el archivo .env, que debería verse así:
MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=07f4dbf61b8122
MAIL_PASSWORD=d7fc5d57bc6eac
MAIL_ENCRYPTION=tls

Una vez que haya terminado, puede usar este código para enviar su primer email de prueba:

<?php
use App\Mail\JustTesting;
use Illuminate\Support\Facades\Mail;
Route::get('/send-mail', function () {
    Mail::to('nuevo_usuario@ejemplo.com')->send(new JustTesting());
    return '¡Se ha enviado un mensaje a Mailtrap!';
});

API

Si quiere integrar Email Testing en su app para pruebas, automatización y pruebas de secuencias automatizadas, aquí está lo que tiene que hacer:

  • Ejecute uno de los siguientes comandos (dependiendo de qué cliente HTTP use):
# Con symfony http client (recomendado)
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7

# O con guzzle http client
composer require railsware/mailtrap-php guzzlehttp/guzzle php-http/guzzle7-adapter
  • Agregue el transporte de Mailtrap en su archivo config.mail.php:
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Configuraciones del Mailer
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // inicio del transporte mailtrap
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // fin del transporte mailtrap
    
    ]
]
  • Inserte su API key en la variable MAILTRAP_API_KEY y establezca el ID de su bandeja de entrada en MAILTRAP_INBOX_ID
    • Para encontrar su API key/token, navegue a Sending Domains → SMTP/API Settings
MAIL_MAILER="mailtrap"

MAILTRAP_HOST="sandbox.api.mailtrap.io"
MAILTRAP_API_KEY="SU_API_KEY_AQUÍ"
MAILTRAP_INBOX_ID=1000001
  • Ejecute el siguiente comando para limpiar el caché de configuración y establecer las nuevas variables:
php artisan config:clear
  • De manera similar al envío, genere una clase Mailable para probar su email, así:
php artisan make:mail WelcomeMail
  • Configure su email; por ejemplo:
<?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;

    /**
     * Crear una nueva instancia del mensaje.
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * Obtener el envelope del mensaje.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address('jeffrey@ejemplo.com', 'Jeffrey Way'),
            replyTo: [
                      new Address('taylor@ejemplo.com', 'Taylor Otwell'),
                  ],
            subject: 'Email de Bienvenida',
            using: [
                      function (Email $email) {
                          // Encabezados
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'ejemplo.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

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

                          // Categoría (debe ser solo una)
                          $email->getHeaders()
                              ->add(new CategoryHeader('Prueba de Integración'))
                          ;
                      },
                  ]
        );
    }

    /**
     * Obtener la definición del contenido del mensaje.
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obtener los adjuntos para el mensaje.
     *
     * @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'),
        ];
    }

    /**
     * Obtener los encabezados para el mensaje.
     */
    public function headers(): Headers
    {
        return new Headers(
            'custom-message-id@ejemplo.com',
            ['previous-message@ejemplo.com'],
            [
                'X-Custom-Header' => 'Custom Value',
            ],
        );
    }
}
  • Usa una plantilla de email (opcional):
# resources/views/mail/welcome-email.blade.php

Hola, {{$name}} y bienvenido aquí 😉

<br>
Programador Divertido
  • Agregue el router CLI:
# app/routes/console.php
<?php

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

/*
|--------------------------------------------------------------------------
| Rutas de Consola
|--------------------------------------------------------------------------
|
*/

Artisan::command('send-welcome-mail', function () {
    Mail::to('destinatario@gmail.com')->send(new WelcomeMail("Jon"));
    // También puede usar un mailer específico si su mailer predeterminado no es "mailtrap" pero quiere usarlo para emails de bienvenida
    // Mail::mailer('mailtrap')->to('destinatario@gmail.com')->send(new WelcomeMail("Juan"));
})->purpose('Enviar email de bienvenida');
  • Envíe su email de prueba con el siguiente comando CLI:
php artisan send-welcome-mail

¿Buscas información adicional? ¡Asegúrese de leer la documentación oficial de la API de Mailtrap!

Conclusión

¡Y eso es todo! Hemos llegado al final de nuestra guía sobre cómo enviar email en HTML con laravel’.

Esperamos que ahora tenga un mejor entendimiento de este popular framework PHP y pueda comenzar a enviar sus emails de inmediato, tanto a través de SMTP como de API.

Si quiere expandir aún más su conocimiento, no dude en consultar nuestros otros artículos dedicados a Laravel, tales 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!