Send emails with Slim
In this quickstart, you'll learn how to send transactional emails from your Slim Framework 4 app with Sidemail. You'll set up the SDK, send your first email, and see examples for common use cases like welcome emails, password resets, and scheduled reports.
Before you start
- Create a Sidemail account → get your API key
- Add a sending domain → set up your domain for sending
1. Install
composer require sidemail/sidemail
2. Configure API key
Add your Sidemail API key to .env:
SIDEMAIL_API_KEY=your-api-key
3. Configure the container
Register the Sidemail client in your DI container (e.g., PHP-DI).
// app/dependencies.php
use Sidemail\Sidemail;
use Psr\Container\ContainerInterface;
return function (ContainerInterface $container) {
$container->set(Sidemail::class, function () {
// The SDK automatically reads SIDEMAIL_API_KEY from env
return new Sidemail();
});
};
4. Send a welcome email
Inject Sidemail\Sidemail into your route handler.
// app/routes.php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Sidemail\Sidemail;
$app->post('/register', function (Request $request, Response $response) {
$data = $request->getParsedBody();
// ... create user ...
// Retrieve Sidemail from the container
$sidemail = $this->get(Sidemail::class);
$sidemail->sendEmail([
'toAddress' => $data['email'],
'fromAddress' => '[email protected]',
'fromName' => 'Your App',
'templateName' => 'Welcome',
'templateProps' => ['firstName' => $data['name']],
]);
$response->getBody()->write('User registered');
return $response;
});
5. Send a password reset email
$app->post('/forgot-password', function (Request $request, Response $response) {
$data = $request->getParsedBody();
$token = 'secure-reset-token';
$sidemail = $this->get(Sidemail::class);
$sidemail->sendEmail([
'toAddress' => $data['email'],
'fromAddress' => '[email protected]',
'fromName' => 'Your App',
'templateName' => 'Password Reset',
'templateProps' => [
'actionUrl' => 'https://myapp.com/reset/' . $token,
],
]);
$response->getBody()->write('Reset link sent');
return $response;
});
6. Send a weekly report (Script)
Create a standalone script for cron jobs.
// scripts/send-weekly-report.php
require __DIR__ . '/../vendor/autoload.php';
use Sidemail\Sidemail;
// Load .env if needed
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();
$sidemail = new Sidemail();
$newSignups = 150;
$chartData = [100, 200, 300, 400, 200, 300, 200, 500];
$sidemail->sendEmail([
'toAddress' => '[email protected]',
'fromAddress' => '[email protected]',
'fromName' => 'My App',
'templateName' => 'Weekly Report',
'templateProps' => [
'signups' => $newSignups,
'chart' => $chartData,
],
]);
echo "Weekly report sent\n";
Run it via cron:
# Run every Monday at 8:00 AM
0 8 * * 1 php scripts/send-weekly-report.php
7. Send email via Middleware
Decouple email sending using Middleware. This is useful for sending emails after a successful request without cluttering your route logic.
// src/Middleware/SendWelcomeEmail.php
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
use Sidemail\Sidemail;
class SendWelcomeEmail
{
private $sidemail;
public function __construct(Sidemail $sidemail)
{
$this->sidemail = $sidemail;
}
public function __invoke(Request $request, RequestHandler $handler): Response
{
$response = $handler->handle($request);
// Only send if registration was successful (e.g. 200 OK)
if ($response->getStatusCode() === 200) {
$data = $request->getParsedBody();
$this->sidemail->sendEmail([
'toAddress' => $data['email'],
'fromAddress' => '[email protected]',
'fromName' => 'My App',
'templateName' => 'Welcome',
]);
}
return $response;
}
}
// Register middleware to the route
$app->post('/register', \App\Action\RegisterAction::class)
->add(SendWelcomeEmail::class);
8. Send HTML email
$app->post('/send-invoice', function (Request $request, Response $response) {
$sidemail = $this->get(Sidemail::class);
$html = '
<div>
<h1>Invoice</h1>
<p>Amount due: $99</p>
</div>
';
$sidemail->sendEmail([
'toAddress' => '[email protected]',
'fromAddress' => '[email protected]',
'fromName' => 'Your App',
'subject' => 'Your Invoice',
'html' => $html,
]);
$response->getBody()->write('Invoice sent');
return $response;
});
9. Send Markdown email
Store your markdown content in a file and load it (learn more).
$markdown = file_get_contents(__DIR__ . '/../templates/emails/welcome.md');
$sidemail->sendEmail([
'toAddress' => '[email protected]',
'fromAddress' => '[email protected]',
'fromName' => 'Your App',
'subject' => 'Testing markdown emails 😊',
'markdown' => $markdown,
'templateProps' => [
'name' => 'John',
'link' => 'https://example.com',
],
]);
10. Send plain text email
$sidemail->sendEmail([
'toAddress' => '[email protected]',
'fromAddress' => '[email protected]',
'fromName' => 'Your App',
'subject' => 'Hello',
'text' => 'Hello! 👋',
]);
11. Schedule email
Send email later. Set scheduledAt to an ISO date string.
$sidemail->sendEmail([
'toAddress' => '[email protected]',
'fromAddress' => '[email protected]',
'fromName' => 'Your App',
'templateName' => 'Welcome',
'templateProps' => ['firstName' => 'Alex'],
'scheduledAt' => (new DateTime('+1 hour'))->format(DateTime::ATOM),
]);
12. Send with attachment
Use the Sidemail::fileToAttachment helper to attach files.
use Sidemail\Sidemail;
$pdfData = file_get_contents('invoice.pdf');
$attachment = Sidemail::fileToAttachment('invoice.pdf', $pdfData);
$sidemail->sendEmail([
'toAddress' => '[email protected]',
'fromAddress' => '[email protected]',
'fromName' => 'Your App',
'subject' => 'Your invoice',
'text' => 'See attached.',
'attachments' => [$attachment],
]);
13. Handle errors
use Sidemail\SidemailException;
try {
$sidemail->sendEmail([/* ... */]);
} catch (SidemailException $e) {
// Log error
error_log($e->getMessage());
$response->withStatus(500)->getBody()->write('Error sending email');
return $response;
}