Creating Dynamic Toast Notifications in Blazor

.NET 7

Blazor is a modern web framework developed by Microsoft that is changing the way developers build interactive web applications. Blazor lets you build rich client-side web experiences using C# and .NET instead of JavaScript. One of the most powerful features of Blazor is its component-based architecture, which encourages the reuse of code and modular design.

To learn more about Blazor Web Development, click here.

In today’s web applications, providing feedback to users in a timely manner is critical to a smooth user experience. Toast notifications are an effective way to deliver messages such as accomplishments, alerts, bugs, and info updates. In this article, we’ll guide you through the creation of a reusable toast notification component in Blazor that will allow you to easily integrate and manage toast notifications throughout your application.

Understanding Blazor and Its Component-Based Architecture

Blazor is part of the ASP.NET Core framework, and it allows you to develop full-stack web applications .NET. Blazor provides a unified programming model that lets you use your .NET skills across the stack, whether you’re building server-side or client-side applications.

Blazor differs from traditional web frameworks by running .NET code in the browser (Blazor WebAssembly) or on the server with SignalR (Blazor Server). This removes the need for JavaScript in many scenarios, providing a more seamless development experience for .NET developers.

Component-Based Framework

Blazor is a component-based framework at its core. In Blazor, everything is a component, from a simple button to a complex data grid. Components are self-contained units of user interface and behavior that can be reused throughout the entire application. They allow developers to encapsulate their HTML, CSS, and C# code in one location, which promotes reusability, maintainability, and testability.

Components can be nested, set parameters, and even share data with each other. This makes Blazor an ideal framework for building modular and dynamic web applications. Once created, components can be used anywhere in the application and are written as .razor files.

In this article, we’ll guide you through the creation of a reusable toast notification component and service in Blazor that will allow you to easily integrate and manage toast notifications throughout your application.

Why Toast Notifications?

Toast Alerts are non-intrusive alerts that automatically fade out after a short period of time. They are perfect for displaying information like ‘data saved successfully’ or ‘error occurred during processing’. Unlike modal dialogs, toasts allow the user to continue working seamlessly, as they do not require user interaction to close.

Building a dynamic and reusable Toast Notification in Blazor

There are multiple ways we can build the toast notifications, either by creating a component or by adding services. We can reuse the component on any page or inject services to call the toast notifications. In this sample, I will be creating a service so that I don’t need to add a component to each page to show the toast notifications. Instead, we can inject the service and call it throughout the application.

Complete Source Code: https://github.com/rijwanansari/Eshal.Blazor

Create a Blazor Web App project template using Visual Studio or VS Code and give a name.

 Visual Studio

You can choose any .NET Core framework. However, for this article, I have used .NET 8.

We’ll start by creating a service that handles triggering the toast notifications. This service will be responsible for raising events that the toast component will listen to in order to display messages.

ToastService.cs

//add namespace
namespace ToastNotificationService.ToastMessage;
public class ToastService
{
    public event Action<string, string, int> OnShow;
    public event Action OnHide;
    public void ShowToast(string message, string type = "info", int dismissAfter = 3)
    {
        OnShow?.Invoke(message, type, dismissAfter);
    }
    public void HideToast()
    {
        OnHide?.Invoke();
    }
    public void ShowSuccess(string message, int dismissAfter = 3) => ShowToast(message, "success", dismissAfter);
    public void ShowError(string message, int dismissAfter = 3) => ShowToast(message, "failure", dismissAfter);
    public void ShowWarning(string message, int dismissAfter = 3) => ShowToast(message, "warning", dismissAfter);
    public void ShowInfo(string message, int dismissAfter = 3) => ShowToast(message, "info", dismissAfter);
    public void ShowAlert(string message, int dismissAfter = 3) => ShowToast(message, "alert", dismissAfter);
}

The ToastService class defines two events: OnShow and OnHide. When ShowToast is called, it triggers the OnShow event, passing the message content, type, and dismissal time. The HideToast method triggers the OnHide event to hide the toast.

Additional methods like ShowSuccess, ShowError, ShowWarning, ShowInfo, and ShowAlert are just to trigger the ShowToast based on type.

Registering the Toast Service

To make the service available throughout the application, register it as a singleton in your Program.cs.

builder.Services.AddSingleton<ToastService>();

This ensures that only one instance of ToastService is used across the application, allowing consistent toast management.

Creating the Toast Component

Now, we’ll create the toast component, which will display the notifications triggered by the ToastService.

Toast. razor

@using ToastNotificationService.ToastMessage
@inject ToastService ToastService
@rendermode RenderMode.InteractiveServer

@if (ShowMessage)
{
    <div class="toast-message-container">
        <div class="toast-message-box @MessageTypeClass">
            <span class="toast-message-content">@MessageContent</span>
            <button class="toast-close-button" @onclick="HideMessage">x</button>
        </div>
    </div>
}
@code {
    private bool ShowMessage { get; set; } = false;
    private string MessageContent { get; set; } = string.Empty;
    private string MessageType { get; set; } = "success"; // default to success
    public int DismissAfter { get; set; } = 3;
    private string MessageTypeClass => MessageType switch
    {
        "success" => "toast-message-success",
        "failure" => "toast-message-failure",
        "alert" => "toast-message-alert",
        "warning" => "toast-message-warning",
        _ => "toast-message-default"
    };
    protected override async Task OnParametersSetAsync()
    {
        if (ShowMessage && DismissAfter > 0)
        {
            await Task.Delay(DismissAfter * 1000);
            HideMessage();
        }
    }
    protected override void OnInitialized()
    {
        ToastService.OnShow += ShowToast;
        ToastService.OnHide += HideMessage;
    }
    private async void ShowToast(string message, string type, int dismissAfter)
    {
        MessageContent = message;
        MessageType = type;
        ShowMessage = true;
        await InvokeAsync(StateHasChanged); // Ensure the UI updates
        if (dismissAfter > 0)
        {
            await Task.Delay(dismissAfter * 1000);
            HideMessage();
        }
    }
    private void HideMessage()
    {
        ShowMessage = false;
        InvokeAsync(StateHasChanged); // Ensure the UI updates
    }
    public void Dispose()
    {
        ToastService.OnShow -= ShowToast;
        ToastService.OnHide -= HideMessage;
    }
}

In this component.

  • The ShowMessage flag controls the visibility of the toast.
  • The MessageTypeClass provides different CSS classes based on the type of message (success, error, warning, or info).
  • The ShowToast method is triggered by the OnShow event, which displays the toast with a given message and type. The toast automatically hides after the specified time if dismissAfter is greater than 0.

Styling the Toast Notifications

To make the toast notifications visually appealing, add the following CSS styles.

Toast.razor.css


.toast-message-container {
    position: fixed;
    top: 20px;
    right: 20px;
    width: 300px;
    z-index: 1000;
    animation: slide-in 0.5s ease-out, slide-out 0.5s ease-in 5s forwards;
}

.toast-message-box {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 15px;
    border-radius: 5px;
    color: white;
    font-weight: bold;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    margin-bottom: 10px;
}

.toast-message-success {
    background-color: #28a745;
}

.toast-message-failure {
    background-color: #dc3545;
}

.toast-message-alert {
    background-color: #ffc107;
    color: #212529;
}

.toast-message-warning {
    background-color: #ff8800;
}

.toast-message-default {
    background-color: #17a2b8;
}

.toast-close-button {
    background: none;
    border: none;
    color: white;
    font-size: 16px;
    font-weight: bold;
    cursor: pointer;
}

    .toast-close-button:hover {
        color: #000;
    }

@keyframes slide-in {
    from {
        transform: translateX(100%);
        opacity: 0;
    }

    to {
        transform: translateX(0);
        opacity: 1;
    }
}

@keyframes slide-out {
    from {
        transform: translateX(0);
        opacity: 1;
    }

    to {
        transform: translateX(100%);
        opacity: 0;
    }
}

Adding Toast Component to Layout

To make the toast notifications available throughout your application, add the Toast component to your main layout.

MainLayout.razor

Adding Toast Component to Layout.

To make the toast notifications available throughout your application, add the Toast component to your main layout.

MainLayout.razor

@using ToastNotificationService.Components.Shared
@inherits LayoutComponentBase

<Toast /> 
<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
        </div>

        <article class="content px-4">
           
            @Body
        </article>
    </main>
</div>

<div id="blazor-error-ui">
    An unhandled error has occurred.
    <a href="" class="reload">Reload</a>
    <a class="dismiss">๐Ÿ—™</a>
</div>

This ensures that the toast component is always available, and any component can trigger a toast notification. You can <Toast /> to main layout so that we can trigger the toast notification throughout the application.

Using Toast Notifications in Components

Now that the toast component is set up, you can trigger toast notifications from any component by injecting the ToastService and calling the ShowToast method.

Example

ToastService.ShowSuccess("Operation Successful!", 5);
ToastService.ShowError("This is a failure message!", 5);
ToastService.ShowAlert("This is an alert message!", 5);
ToastService.ShowWarning("This is an alert message!", 5);

I have implemented the toast service on the home page, as illustrated.

@page "/"
@using ToastNotificationService.ToastMessage
@inject ToastService ToastService
@rendermode RenderMode.InteractiveServer

<PageTitle>Home</PageTitle>

<h3>Toast Service Demo</h3>

<button class="btn btn-success" @onclick="ShowSuccessToast">Show Success Toast</button>
<button class="btn btn-danger" @onclick="ShowFailureToast">Show Failure Toast</button>
<button class="btn" @onclick="ShowAlertToast">Show Alert Toast</button>
<button class="btn btn-warning" @onclick="ShowWarningToast">Show Warning Toast</button>

@code {
    private void ShowSuccessToast()
    {
        ToastService.ShowSuccess("Operation Successful!", 5);
    }

    private void ShowFailureToast()
    {
        ToastService.ShowError("This is a failure message!", 5);
    }

    private void ShowAlertToast()
    {
        ToastService.ShowAlert("This is an alert message!", 5);
    }

    private void ShowWarningToast()
    {
        ToastService.ShowWarning("This is an alert message!", 5);
    }
}

In this example, clicking the button triggers a success toast notification that disappears after 5 seconds.

Folder structure

Folder structure

The output of this reusable toast notification is shown below.

Now, we can reuse this Toast Notification throughout the application by simply injecting the ToastService and calling functions.

Conclusion

Toast notifications are an essential part of modern web applications, providing users with timely and unobtrusive feedback. By creating a reusable toast component in Blazor, you can streamline your application’s user experience with minimal code. This approach allows for centralized control of notifications and consistent styling across your application.

With this setup, you’re well-equipped to handle various types of notifications in your Blazor applications. You can further customize the toast component to fit your specific needs, such as adding animations or different dismiss behaviors.

Feel free to experiment and enhance this component to suit your application’s requirements!


Similar Articles