diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor
index 0419b3be04..45496a7984 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor
@@ -18,6 +18,7 @@
+
@Body
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertList.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertList.cs
new file mode 100644
index 0000000000..47a26ad9ea
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertList.cs
@@ -0,0 +1,32 @@
+using System.Collections.ObjectModel;
+
+namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
+{
+ public class AlertList : ObservableCollection
+ {
+ public void Add(AlertType type, string text, string title = null, bool dismissible = true)
+ {
+ Add(new AlertMessage(type, text, title, dismissible));
+ }
+
+ public void Info(string text, string title = null, bool dismissible = true)
+ {
+ Add(new AlertMessage(AlertType.Info, text, title, dismissible));
+ }
+
+ public void Warning(string text, string title = null, bool dismissible = true)
+ {
+ Add(new AlertMessage(AlertType.Warning, text, title, dismissible));
+ }
+
+ public void Danger(string text, string title = null, bool dismissible = true)
+ {
+ Add(new AlertMessage(AlertType.Danger, text, title, dismissible));
+ }
+
+ public void Success(string text, string title = null, bool dismissible = true)
+ {
+ Add(new AlertMessage(AlertType.Success, text, title, dismissible));
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertManager.cs
new file mode 100644
index 0000000000..290c36848a
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertManager.cs
@@ -0,0 +1,14 @@
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
+{
+ public class AlertManager : IAlertManager, IScopedDependency
+ {
+ public AlertList Alerts { get; }
+
+ public AlertManager()
+ {
+ Alerts = new AlertList();
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertMessage.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertMessage.cs
new file mode 100644
index 0000000000..e8a8f3529a
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertMessage.cs
@@ -0,0 +1,30 @@
+using JetBrains.Annotations;
+
+namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
+{
+ public class AlertMessage
+ {
+ [NotNull]
+ public string Text
+ {
+ get => _text;
+ set => _text = Check.NotNullOrWhiteSpace(value, nameof(value));
+ }
+ private string _text;
+
+ public AlertType Type { get; set; }
+
+ [CanBeNull]
+ public string Title { get; set; }
+
+ public bool Dismissible { get; set; }
+
+ public AlertMessage(AlertType type, [NotNull] string text, string title = null, bool dismissible = true)
+ {
+ Type = type;
+ Text = Check.NotNullOrWhiteSpace(text, nameof(text));
+ Title = title;
+ Dismissible = dismissible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertType.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertType.cs
new file mode 100644
index 0000000000..6a61a9995f
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertType.cs
@@ -0,0 +1,15 @@
+namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
+{
+ public enum AlertType
+ {
+ Default,
+ Primary,
+ Secondary,
+ Success,
+ Danger,
+ Warning,
+ Info,
+ Light,
+ Dark
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/IAlertManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/IAlertManager.cs
new file mode 100644
index 0000000000..f30fe4c262
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/IAlertManager.cs
@@ -0,0 +1,7 @@
+namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
+{
+ public interface IAlertManager
+ {
+ AlertList Alerts { get; }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/AlertWrapper.cs b/framework/src/Volo.Abp.BlazoriseUI/Components/AlertWrapper.cs
new file mode 100644
index 0000000000..d5963a532f
--- /dev/null
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/AlertWrapper.cs
@@ -0,0 +1,10 @@
+using Volo.Abp.AspNetCore.Components.WebAssembly.Alerts;
+
+namespace Volo.Abp.BlazoriseUI.Components
+{
+ internal class AlertWrapper
+ {
+ public AlertMessage AlertMessage { get; set; }
+ public bool IsVisible { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor
new file mode 100644
index 0000000000..c46747c9a6
--- /dev/null
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor
@@ -0,0 +1,16 @@
+@foreach (var alert in Alerts)
+{
+
+ @if (!string.IsNullOrEmpty(alert.AlertMessage.Title))
+ {
+
+ @alert.AlertMessage.Title
+ @if (alert.AlertMessage.Dismissible)
+ {
+
+ }
+
+ }
+ @alert.AlertMessage.Text
+
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor.cs b/framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor.cs
new file mode 100644
index 0000000000..b0035b1f11
--- /dev/null
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using Blazorise;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Routing;
+using Volo.Abp.AspNetCore.Components.WebAssembly.Alerts;
+
+namespace Volo.Abp.BlazoriseUI.Components
+{
+ public partial class PageAlert : ComponentBase, IDisposable
+ {
+ private List Alerts = new List();
+
+ [Inject]
+ protected IAlertManager AlertManager { get; set; }
+
+ [Inject]
+ protected NavigationManager NavigationManager { get; set; }
+
+ protected override void OnInitialized()
+ {
+ base.OnInitialized();
+ NavigationManager.LocationChanged += NavigationManager_LocationChanged;
+ AlertManager.Alerts.CollectionChanged += Alerts_CollectionChanged;
+
+ Alerts.AddRange(AlertManager.Alerts.Select(t => new AlertWrapper
+ {
+ AlertMessage = t,
+ IsVisible = true
+ }));
+ }
+
+ //Since Blazor WASM doesn't support scoped dependency, we need to clear alerts on each location changed event.
+ private void NavigationManager_LocationChanged(object sender, LocationChangedEventArgs e)
+ {
+ AlertManager.Alerts.Clear();
+ Alerts.Clear();
+ }
+
+ private void Alerts_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.Action == NotifyCollectionChangedAction.Add)
+ {
+ foreach (var item in e.NewItems)
+ {
+ Alerts.Add(new AlertWrapper
+ {
+ AlertMessage = (AspNetCore.Components.WebAssembly.Alerts.AlertMessage)item,
+ IsVisible = true
+ });
+ }
+ }
+ StateHasChanged();
+ }
+
+ protected virtual Color GetAlertColor(AlertType alertType)
+ {
+ var color = alertType switch
+ {
+ AlertType.Info => Color.Info,
+ AlertType.Success => Color.Success,
+ AlertType.Warning => Color.Warning,
+ AlertType.Danger => Color.Danger,
+ AlertType.Dark => Color.Dark,
+ AlertType.Default => Color.None,
+ AlertType.Light => Color.Light,
+ AlertType.Primary => Color.Primary,
+ AlertType.Secondary => Color.Secondary,
+ _ => Color.None,
+ };
+
+ return color;
+ }
+
+ public void Dispose()
+ {
+ NavigationManager.LocationChanged -= NavigationManager_LocationChanged;
+ AlertManager.Alerts.CollectionChanged -= Alerts_CollectionChanged;
+ }
+ }
+}
\ No newline at end of file