{"id":497,"date":"2025-08-29T07:47:27","date_gmt":"2025-08-29T07:47:27","guid":{"rendered":"https:\/\/1v0.net\/blog\/?p=497"},"modified":"2025-08-29T08:14:39","modified_gmt":"2025-08-29T08:14:39","slug":"mastering-laravel-notifications-mail-sms-and-slack","status":"publish","type":"post","link":"https:\/\/1v0.net\/blog\/mastering-laravel-notifications-mail-sms-and-slack\/","title":{"rendered":"Mastering Laravel Notifications: Mail, SMS, and Slack"},"content":{"rendered":"\n<p>Laravel Notifications provide a clean and powerful way to send alerts to users across multiple channels such as <strong>email<\/strong>, <strong>SMS<\/strong>, and <strong>Slack<\/strong>. Whether you\u2019re building sign-up confirmations, payment updates, or system alerts, Laravel 12 makes it straightforward. In this guide, we\u2019ll cover how to configure providers in <code>.env<\/code>, create reusable notification classes, trigger them from controllers and events, display them in your application\u2019s UI, and test them effectively.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Configure Notification Channels in Laravel 12 (.env setup)<\/strong><\/h2>\n\n\n\n<p>Laravel supports multiple notification channels. You configure them in the <code>.env<\/code> file. Here are some examples:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># Default Mail driver (SMTP)<\/span>\nMAIL_MAILER=smtp\nMAIL_HOST=smtp.mailtrap.io\nMAIL_PORT=587\nMAIL_USERNAME=your_smtp_username\nMAIL_PASSWORD=your_smtp_password\nMAIL_ENCRYPTION=tls\nMAIL_FROM_ADDRESS=no-reply@example.com\nMAIL_FROM_NAME=<span class=\"hljs-string\">\"My App\"<\/span>\n\n<span class=\"hljs-comment\"># Mailgun<\/span>\nMAIL_MAILER=mailgun\nMAILGUN_DOMAIN=your-domain.com\nMAILGUN_SECRET=your-mailgun-key\nMAILGUN_ENDPOINT=api.mailgun.net\n\n<span class=\"hljs-comment\"># Postmark<\/span>\nMAIL_MAILER=postmark\nPOSTMARK_TOKEN=your-postmark-server-token\n\n<span class=\"hljs-comment\"># Slack Webhook<\/span>\nSLACK_WEBHOOK_URL=https:\/\/hooks.slack.com\/services\/xxxx\/yyyy\/zzzz\n\n<span class=\"hljs-comment\"># Nexmo (Vonage)<\/span>\nNEXMO_KEY=your-nexmo-key\nNEXMO_SECRET=your-nexmo-secret\nNEXMO_SMS_FROM=MyApp\n\n<span class=\"hljs-comment\"># Twilio<\/span>\nTWILIO_SID=your-twilio-sid\nTWILIO_TOKEN=your-twilio-token\nTWILIO_FROM=+1234567890<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>These environment variables tell Laravel which service to use for each channel. For example, <code>MAIL_MAILER=mailgun<\/code> will route all email notifications through Mailgun, and <code>SLACK_WEBHOOK_URL<\/code> allows Slack messages to be posted to your workspace.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Send Laravel Notifications via Mail (SMTP)<\/strong><\/h2>\n\n\n\n<p>First, create a notification class with Artisan:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan make:notification UserRegisteredNotification<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This generates a file under <code>app\/Notifications<\/code>. Inside, define the email content:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Notifications<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Bus<\/span>\\<span class=\"hljs-title\">Queueable<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Notifications<\/span>\\<span class=\"hljs-title\">Notification<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Notifications<\/span>\\<span class=\"hljs-title\">Messages<\/span>\\<span class=\"hljs-title\">MailMessage<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserRegisteredNotification<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Notification<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Queueable<\/span>;\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">via<\/span><span class=\"hljs-params\">(object $notifiable)<\/span>: <span class=\"hljs-title\">array<\/span>\n    <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> &#91;<span class=\"hljs-string\">'mail'<\/span>];\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">toMail<\/span><span class=\"hljs-params\">(object $notifiable)<\/span>: <span class=\"hljs-title\">MailMessage<\/span>\n    <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> (<span class=\"hljs-keyword\">new<\/span> MailMessage)\n            -&gt;subject(<span class=\"hljs-string\">'Welcome to My App'<\/span>)\n            -&gt;greeting(<span class=\"hljs-string\">'Hello '<\/span> . $notifiable-&gt;name)\n            -&gt;line(<span class=\"hljs-string\">'Thanks for joining our platform!'<\/span>)\n            -&gt;action(<span class=\"hljs-string\">'Visit Dashboard'<\/span>, url(<span class=\"hljs-string\">'\/dashboard'<\/span>))\n            -&gt;line(<span class=\"hljs-string\">'We\u2019re excited to have you onboard.'<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><code>via()<\/code> defines the channel, while <code>toMail()<\/code> builds the email with subject, body, and a call-to-action button.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Send Laravel Notifications via SMS (Nexmo or Twilio)<\/strong><\/h2>\n\n\n\n<p>Once your Nexmo or Twilio credentials are in <code>.env<\/code>, extend your notification to also deliver SMS:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Notifications<\/span>\\<span class=\"hljs-title\">Messages<\/span>\\<span class=\"hljs-title\">NexmoMessage<\/span>;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">via<\/span><span class=\"hljs-params\">(object $notifiable)<\/span>: <span class=\"hljs-title\">array<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> &#91;<span class=\"hljs-string\">'mail'<\/span>, <span class=\"hljs-string\">'nexmo'<\/span>];\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">toNexmo<\/span><span class=\"hljs-params\">(object $notifiable)<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> (<span class=\"hljs-keyword\">new<\/span> NexmoMessage)\n        -&gt;content(<span class=\"hljs-string\">'Hi '<\/span> . $notifiable-&gt;name . <span class=\"hljs-string\">', welcome to My App!'<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This ensures both an email and an SMS are sent when you call <code>notify()<\/code>. For Twilio, use a Twilio channel package with a <code>toTwilio()<\/code> method.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Send Laravel Notifications to Slack<\/strong><\/h2>\n\n\n\n<p>After setting your <code>SLACK_WEBHOOK_URL<\/code>, you can notify a Slack channel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Notifications<\/span>\\<span class=\"hljs-title\">Messages<\/span>\\<span class=\"hljs-title\">SlackMessage<\/span>;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">via<\/span><span class=\"hljs-params\">(object $notifiable)<\/span>: <span class=\"hljs-title\">array<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> &#91;<span class=\"hljs-string\">'slack'<\/span>];\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">toSlack<\/span><span class=\"hljs-params\">(object $notifiable)<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> (<span class=\"hljs-keyword\">new<\/span> SlackMessage)\n        -&gt;success()\n        -&gt;content(<span class=\"hljs-string\">'\ud83d\ude80 New user registered: '<\/span> . $notifiable-&gt;email);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Whenever <code>$user-&gt;notify()<\/code> is called, a message will also appear in your Slack channel.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Trigger Notifications from a Controller<\/strong><\/h2>\n\n\n\n<p>Notify a user immediately after registration inside your controller:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$user-&gt;notify(<span class=\"hljs-keyword\">new<\/span> UserRegisteredNotification());<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This approach is simple but ties notification logic directly to the controller action. For bigger apps, consider using events.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Trigger Notifications with Events<\/strong><\/h2>\n\n\n\n<p>Fire an event in your controller and handle the notification in a listener:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ Listener example<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SendUserNotification<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handle<\/span><span class=\"hljs-params\">(UserRegistered $event)<\/span>: <span class=\"hljs-title\">void<\/span>\n    <\/span>{\n        $event-&gt;user-&gt;notify(<span class=\"hljs-keyword\">new<\/span> UserRegisteredNotification());\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This decouples notification logic from controllers and lets you attach multiple listeners for additional tasks.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Display Notifications in the Blade UI<\/strong><\/h2>\n\n\n\n<p>Show a user\u2019s notifications directly on their dashboard:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">@<span class=\"hljs-keyword\">foreach<\/span> (auth()-&gt;user()-&gt;notifications <span class=\"hljs-keyword\">as<\/span> $notification)\n    &lt;div <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span>=\"<span class=\"hljs-title\">alert<\/span> <span class=\"hljs-title\">alert<\/span>-<span class=\"hljs-title\">info<\/span>\"&gt;\n        <\/span>{{ $notification-&gt;data&#91;<span class=\"hljs-string\">'message'<\/span>] ?? <span class=\"hljs-string\">'New Notification'<\/span> }}\n    &lt;\/div&gt;\n@<span class=\"hljs-keyword\">endforeach<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This simple loop displays messages for the authenticated user. You can enhance it with Bootstrap components, icons, and read\/unread states.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Testing Notifications with PHPUnit<\/strong><\/h2>\n\n\n\n<p>Fake notifications in tests to verify they are sent correctly without calling external services:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Notification::fake();\n\n$user = User::factory()-&gt;create();\n$user-&gt;notify(<span class=\"hljs-keyword\">new<\/span> UserRegisteredNotification());\n\nNotification::assertSentTo(\n    $user,\n    UserRegisteredNotification::class\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><code>Notification::fake()<\/code> prevents delivery, while <code>assertSentTo()<\/code> confirms the notification was dispatched to the intended recipient.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wrapping Up<\/strong><\/h2>\n\n\n\n<p>Laravel\u2019s notification system lets you send messages via email, SMS, and Slack with ease. You learned how to configure providers in <code>.env<\/code>, create a notification class, use them inside controllers, dispatch via events for cleaner architecture, render notifications in the UI, and test them effectively. These skills help you deliver timely communication while keeping code maintainable and scalable.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>FAQ: Laravel Notifications<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How do I send an email notification in Laravel 12?<\/strong>  \nUse the <code>notify()<\/code> method on a notifiable model and define a <code>toMail()<\/code> method in your notification class.<\/li>\n\n<li><strong>Can I send SMS notifications in Laravel?<\/strong>  \nYes. Configure Nexmo or Twilio in <code>.env<\/code> and add <code>toNexmo()<\/code> or <code>toTwilio()<\/code> methods in your notification class.<\/li>\n\n<li><strong>How do I send Slack notifications?<\/strong>  \nSet <code>SLACK_WEBHOOK_URL<\/code> in <code>.env<\/code> and implement <code>toSlack()<\/code> in your notification class using <code>SlackMessage<\/code>.<\/li>\n\n<li><strong>Should I use controllers or events for notifications?<\/strong>  \nControllers are fine for small apps. For scalable apps, dispatch events and let listeners send notifications.<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What\u2019s Next<\/strong><\/h2>\n\n\n\n<p>Keep building a robust communication system by checking out these related guides:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/blog\/how-to-queue-emails-in-laravel-for-faster-delivery\">How to Queue Emails in Laravel for Faster Delivery<\/a><\/li>\n<li><a href=\"\/blog\/laravel-events-listeners-complete-guide\">Laravel Events and Listeners: A Complete Guide<\/a><\/li>\n<li><a href=\"\/blog\/using-laravel-telescope-to-debug-performance-issues\">Using Laravel Telescope to Debug Performance Issues<\/a><\/li>\n<\/ul>\n\n","protected":false},"excerpt":{"rendered":"<p>Laravel Notifications provide a clean and powerful way to send alerts to users across multiple channels such as email, SMS, and Slack. Whether you\u2019re building sign-up confirmations, payment updates, or system alerts, Laravel 12 makes it straightforward. In this guide, we\u2019ll cover how to configure providers in .env, create reusable notification classes, trigger them from [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":501,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[46,61,91,92,62],"class_list":["post-497","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","tag-events","tag-mail","tag-notifications","tag-slack","tag-sms"],"_links":{"self":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/497","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/comments?post=497"}],"version-history":[{"count":2,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/497\/revisions"}],"predecessor-version":[{"id":505,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/497\/revisions\/505"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media\/501"}],"wp:attachment":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media?parent=497"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/categories?post=497"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/tags?post=497"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}