diff --git a/app/Livewire/Notifications/Slack.php b/app/Livewire/Notifications/Slack.php
index 58cab54941..c101941ec6 100644
--- a/app/Livewire/Notifications/Slack.php
+++ b/app/Livewire/Notifications/Slack.php
@@ -29,6 +29,9 @@ class Slack extends Component
#[Validate(['nullable', new SafeWebhookUrl])]
public ?string $slackWebhookUrl = null;
+ #[Validate(['boolean'])]
+ public bool $includeProjectNameInTitle = false;
+
#[Validate(['boolean'])]
public bool $deploymentSuccessSlackNotifications = false;
@@ -90,6 +93,7 @@ public function syncData(bool $toModel = false)
$this->authorize('update', $this->settings);
$this->settings->slack_enabled = $this->slackEnabled;
$this->settings->slack_webhook_url = $this->slackWebhookUrl;
+ $this->settings->include_project_name_in_title = $this->includeProjectNameInTitle;
$this->settings->deployment_success_slack_notifications = $this->deploymentSuccessSlackNotifications;
$this->settings->deployment_failure_slack_notifications = $this->deploymentFailureSlackNotifications;
@@ -113,6 +117,7 @@ public function syncData(bool $toModel = false)
$this->slackWebhookUrl = auth()->user()->can('update', $this->settings)
? $this->settings->slack_webhook_url
: null;
+ $this->includeProjectNameInTitle = $this->settings->include_project_name_in_title;
$this->deploymentSuccessSlackNotifications = $this->settings->deployment_success_slack_notifications;
$this->deploymentFailureSlackNotifications = $this->settings->deployment_failure_slack_notifications;
diff --git a/app/Models/SlackNotificationSettings.php b/app/Models/SlackNotificationSettings.php
index 62603685e9..eac32b970c 100644
--- a/app/Models/SlackNotificationSettings.php
+++ b/app/Models/SlackNotificationSettings.php
@@ -16,6 +16,7 @@ class SlackNotificationSettings extends Model
'slack_enabled',
'slack_webhook_url',
+ 'include_project_name_in_title',
'deployment_success_slack_notifications',
'deployment_failure_slack_notifications',
@@ -40,6 +41,7 @@ class SlackNotificationSettings extends Model
protected $casts = [
'slack_enabled' => 'boolean',
'slack_webhook_url' => 'encrypted',
+ 'include_project_name_in_title' => 'boolean',
'deployment_success_slack_notifications' => 'boolean',
'deployment_failure_slack_notifications' => 'boolean',
diff --git a/app/Notifications/Application/DeploymentFailed.php b/app/Notifications/Application/DeploymentFailed.php
index 8fff7f03bb..04e0e5c0c0 100644
--- a/app/Notifications/Application/DeploymentFailed.php
+++ b/app/Notifications/Application/DeploymentFailed.php
@@ -182,7 +182,8 @@ public function toSlack(): SlackMessage
return new SlackMessage(
title: $title,
description: $description,
- color: SlackMessage::errorColor()
+ color: SlackMessage::errorColor(),
+ projectName: data_get($this->application, 'environment.project.name'),
);
}
diff --git a/app/Notifications/Application/DeploymentSuccess.php b/app/Notifications/Application/DeploymentSuccess.php
index 415df5831d..1c1b1e2dd4 100644
--- a/app/Notifications/Application/DeploymentSuccess.php
+++ b/app/Notifications/Application/DeploymentSuccess.php
@@ -202,7 +202,8 @@ public function toSlack(): SlackMessage
return new SlackMessage(
title: $title,
description: $description,
- color: SlackMessage::successColor()
+ color: SlackMessage::successColor(),
+ projectName: data_get($this->application, 'environment.project.name'),
);
}
diff --git a/app/Notifications/Channels/SlackChannel.php b/app/Notifications/Channels/SlackChannel.php
index cddb7a5611..42b1ac828e 100644
--- a/app/Notifications/Channels/SlackChannel.php
+++ b/app/Notifications/Channels/SlackChannel.php
@@ -19,6 +19,10 @@ public function send(SendsSlack $notifiable, Notification $notification): void
return;
}
+ if ($slackSettings->include_project_name_in_title) {
+ $message->prependProjectNameToTitle();
+ }
+
SendMessageToSlackJob::dispatch($message, $slackSettings->slack_webhook_url);
}
}
diff --git a/app/Notifications/Dto/SlackMessage.php b/app/Notifications/Dto/SlackMessage.php
index 879bf65472..b0bc09c24e 100644
--- a/app/Notifications/Dto/SlackMessage.php
+++ b/app/Notifications/Dto/SlackMessage.php
@@ -7,9 +7,19 @@ class SlackMessage
public function __construct(
public string $title,
public string $description,
- public string $color = '#0099ff'
+ public string $color = '#0099ff',
+ public ?string $projectName = null,
) {}
+ public function prependProjectNameToTitle(): void
+ {
+ if ($this->projectName === null || $this->projectName === '') {
+ return;
+ }
+
+ $this->title = "{$this->projectName}: {$this->title}";
+ }
+
public static function infoColor(): string
{
return '#0099ff';
diff --git a/database/migrations/2026_07_14_000000_add_include_project_name_in_title_to_slack_notification_settings.php b/database/migrations/2026_07_14_000000_add_include_project_name_in_title_to_slack_notification_settings.php
new file mode 100644
index 0000000000..bab0c8b3e8
--- /dev/null
+++ b/database/migrations/2026_07_14_000000_add_include_project_name_in_title_to_slack_notification_settings.php
@@ -0,0 +1,22 @@
+boolean('include_project_name_in_title')->default(false);
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('slack_notification_settings', function (Blueprint $table) {
+ $table->dropColumn('include_project_name_in_title');
+ });
+ }
+};
diff --git a/resources/views/livewire/notifications/slack.blade.php b/resources/views/livewire/notifications/slack.blade.php
index 9ab7522918..0a32852c71 100644
--- a/resources/views/livewire/notifications/slack.blade.php
+++ b/resources/views/livewire/notifications/slack.blade.php
@@ -45,6 +45,9 @@
label="Deployment Success" />
+
diff --git a/tests/Feature/SlackNotificationProjectNameTest.php b/tests/Feature/SlackNotificationProjectNameTest.php
new file mode 100644
index 0000000000..c767eaee2e
--- /dev/null
+++ b/tests/Feature/SlackNotificationProjectNameTest.php
@@ -0,0 +1,78 @@
+ 0]);
+});
+
+it('prefixes a Slack title with the project name when enabled', function () {
+ Queue::fake();
+
+ $team = Team::factory()->create();
+ $project = Project::factory()->create([
+ 'name' => 'My Project',
+ 'team_id' => $team->id,
+ ]);
+ $environment = Environment::factory()->create(['project_id' => $project->id]);
+ $application = Application::factory()->create(['environment_id' => $environment->id]);
+
+ expect($team->slackNotificationSettings->include_project_name_in_title)->toBeFalse();
+
+ $team->slackNotificationSettings->update([
+ 'slack_enabled' => true,
+ 'slack_webhook_url' => 'https://hooks.slack.com/services/test',
+ 'include_project_name_in_title' => true,
+ ]);
+ $notification = new DeploymentFailed($application, 'deployment-uuid');
+ $message = $notification->toSlack();
+
+ app(SlackChannel::class)->send($team, $notification);
+
+ expect($message->projectName)->toBe('My Project');
+ Queue::assertPushed(SendMessageToSlackJob::class, function (SendMessageToSlackJob $job) {
+ $message = (new ReflectionProperty($job, 'message'))->getValue($job);
+
+ return $message->title === 'My Project: Deployment failed';
+ });
+});
+
+it('keeps the original Slack title when the project name option is disabled', function () {
+ Queue::fake();
+
+ $team = Team::factory()->create();
+ $project = Project::factory()->create([
+ 'name' => 'My Project',
+ 'team_id' => $team->id,
+ ]);
+ $environment = Environment::factory()->create(['project_id' => $project->id]);
+ $application = Application::factory()->create(['environment_id' => $environment->id]);
+ $team->slackNotificationSettings->update([
+ 'slack_enabled' => true,
+ 'slack_webhook_url' => 'https://hooks.slack.com/services/test',
+ 'include_project_name_in_title' => false,
+ ]);
+ $notification = new DeploymentSuccess($application, 'deployment-uuid');
+ $message = $notification->toSlack();
+
+ app(SlackChannel::class)->send($team, $notification);
+
+ expect($message->projectName)->toBe('My Project');
+ Queue::assertPushed(SendMessageToSlackJob::class, function (SendMessageToSlackJob $job) {
+ $message = (new ReflectionProperty($job, 'message'))->getValue($job);
+
+ return $message->title === 'New version successfully deployed';
+ });
+});