# Sending emails

Kirby has a built-in email engine, which can be used to send notifications to your users, replies to filled in contact forms and more.

****

<info>
It's highly recommended to <a href="#transport-configuration">add a transport configuration</a> to increase the chances that your emails will be accepted and received by the recipients.
</info>

## Send an email
### Simple

```php
try {
  $kirby->email([
    'from'    => 'welcome@supercompany.com',
    'replyTo' => 'no-reply@supercompany.com',
    'to'      => 'someone@gmail.com',
    'cc'      => 'anotherone@gmail.com',
    'bcc'     => 'secret@gmail.com',
    'subject' => 'Welcome!',
    'body'    => 'It\'s great to have you with us',
  ]);
} catch (Exception $error) {
  // Errors will be thrown as Exceptions.
  // If you want to notice/output errors,
  // always use try-catch.

  echo $error;
}
```

### With custom sender name

```php
$from = new \Kirby\Cms\User([
  'email' => 'e@mail.com',
  'name'  => 'Vorname Nachname',
]);

try {
  $kirby->email([
    'from'    => $from,
    'to'      => 'someone@example.com',
    'subject' => 'Welcome!',
    'body'    => 'It\'s great to have you with us',
  ]);
} catch (Exception $error) {
  echo $error;
}
```

### With multiple recipients:

```php
$kirby->email([
  'from' => 'welcome@supercompany.com',
  'to'   => [
    'someone@gmail.com',
    'numbertwo@gmail.com'
  ],
  'subject' => 'Welcome!',
  'body'    => 'It\'s great to have you with us',
]);

// or with a collection of users

$kirby->email([
  'to' => $kirby->users()->filterBy('role', 'newbies'),
  …
]);
```

## Formats

<info>
Like all other template names, also email template names must be lowercase.
</info>

### Plain Text

```php
$kirby->email([
  'to'       => 'peter@lustig.de',
  'template' => 'my-email',
  'data'     => [
    'num' => '2'
  ]
]);
```

```php "/site/templates/emails/my-email.php"
Welcome to Newsletter No. <?= $num ?>!
```

<info>
PHP may swallow a newline if a printed variable like `<?= $variable ?>` is placed at the end of a line. This is especially noticeable in plain-text email templates, so don't rely on an end-of-line `<?= ... ?>` alone when a preserved line break is important.
</info>

### HTML & Plain Text

```php "/site/templates/emails/media.html.php"
<h1>Hi <?= $name ?></h1>
<p><?= $text ?></p>
```

```php "in site/templates/emails/media.text.php"
Hi <?= $name ?>,

<?= $text ?>
```

```php
$kirby->email([
  'template' => 'media',
  'data'     => [
    'name' => 'Peter',
    'text' => 'welcome to our wonderful email list'
  ]
]);
```

### Directly set body without template

```php
$kirby->email([
  'from'    => 'welcome@supercompany.com',
  'to'      => 'someone@gmail.com',
  'subject' => 'Welcome!',
  'body' => [
      'html' => Html::a('https://getkirby.com'),
      'text' => 'https://getkirby.com',
  ],
]);
```

## Personalize emails to multiple users

```php
foreach ($users as $user) {
  try {
    $kirby->email('management', [
      'to'       => $user,
      'template' => 'user-specific',
      'data'     => [
        'user' => $user
      ]
    ]);
  } catch (Exception $error) {
    echo $error;
  }
}
```
```php "/site/templates/emails/user-specific.php"
Welcome, <?= $user->name() ?>!
Great to have you with us since <?= $user->yearJoinedCompany() ?>.
```

## Attachments

```php
$kirby->email([
  'from'        => 'welcome@supercompany.com',
  'to'          => 'someone@gmail.com',
  'subject'     => 'Welcome!',
  'body'        => 'Here are some attachments',
  'attachments' => [
    $page->file('somefile.jpg'),
    $page->file('someotherfile.jpg')
  ]
]);
```

## Check if email is sent successfully

```php
$success = $kirby->email([
    'from'    => 'welcome@supercompany.com',
    'to'      => 'someone@gmail.com',
    'subject' => 'Welcome!',
    'body'    => 'We will never reply',
])->isSent();
```

## Presets

If you keep using the same options over and over in your controllers, models or elsewhere, setting up email presets in your config file can help you to keep your code lean and clean:

```php "/site/config/config.php"
return [
  'email' => [
    'presets' => [
      'contact' => [
        'from'    => 'no-reply@supercompany.com',
        'subject' => 'Thank you for your contact request',
        'cc'      => 'marketing@supercompany.com',
        'body'    => 'We will never reply'
      ]
    ]
  ]
];
```

You can then call the email method and pass the preset name as first argument and any options you want to add/customize for this specific email as second argument:

```php
$kirby->email('contact', [
  'to' => 'peter@lustig.de'
]);
```

## Transport configuration

Many web hosts impose strict limits on the number of emails the PHP mail feature can send, which can result in delays or non-delivery of your emails. In addition, because these emails are sent from your web server, the server's reputation has a significant impact on email deliverability. If your web server has a poor reputation, your emails may end up in recipients' spam folders or be blocked altogether.

To avoid this, it is recommended to add an email transport configuration, most commonly an SMTP server:

```php "/site/config/config.php"
return [
  'email' => [
    'transport' => [
      'type'     => 'smtp',
      'host'     => 'smtp.company.com',
      'port'     => 465,
      'security' => true
    ]
  ]
];
```

Read about more details/options of the <a href="https://getkirby.com/docs/reference/system/options/email#email-transport">`email.transport` config option</a>.

## Access PHPMailer

You can get access to the underlying PHPMailer instance via the `beforeSend` callback:

```php
$kirby->email([
  // …
  'beforeSend' => function ($mailer) {
    $mailer->SMTPOptions = [
      'ssl' => [
        'verify_peer'       => false,
        'verify_peer_name'  => false,
        'allow_self_signed' => true
      ]
    ];

    return $mailer;
  }
]);
```

It can be useful to add embedded images:

```php "/site/templates/emails/email.html.php"
<img src="cid:image">
<!-- Email content -->
```

```php
$kirby->email([
  // …
  'template' => 'email',
  'beforeSend' => function ($mailer) {
    $image = asset('assets/images/logo.png');
    $mailer->AddEmbeddedImage($image->root(), 'image', $image->filename(), 'base64', $image->mime());

    return $mailer;
  }
]);
```

The `beforeSend` callback can also be added as [preset](#email-presets).

## More information
- `$kirby->email()`
- <a href="https://getkirby.com/docs/cookbook/forms/basic-contact-form">Email contact form</a>
- <a href="https://getkirby.com/docs/cookbook/forms/email-with-attachments">Email with attachments</a>