🚚 How to migrate to Kirby Tips & tutorials
Skip to content

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.

It's highly recommended to add a transport configuration to increase the chances that your emails will be accepted and received by the recipients.

Send an email

Simple

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

$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:

$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

Plain Text

$kirby->email([
  'to'       => 'peter@lustig.de',
  'template' => 'my-email',
  'data'     => [
    'num' => '2'
  ]
]);
/site/templates/emails/my-email.php
Welcome to Newsletter No. <?= $num ?>!

HTML & Plain Text

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

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

Directly set body without template

$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

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

Attachments

$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

$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:

/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:

$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:

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

Read about more details/options of the email.transport config option.

Access PHPMailer

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

$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:

/site/templates/emails/email.html.php
<img src="cid:image">
<!-- Email content -->
$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.

More information