Success!

Thank you for your message! We'll get back to you soon.

Your subscription to Learn Beyond BC newsletter has been received. Expect expert Business Central insights delivered to your inbox!

Subscribe to Newsletter

Get the latest Business Central insights delivered to your inbox!

Coming Soon!

This feature is coming imminently. Stay tuned!

Me, Myself and I are working hard to bring you something amazing.
Keep exploring and check back soon for updates!

Dynamics 365 Business Central: Silent Signals Using the Notification Data Type

BUSINESS CENTRAL 8 min read Aug 23, 2025

Dynamics 365 Business Central: Silent Signals Using the Notification Data Type

JB

Jeffrey Bulanadi

Software Artisan, Visionary & Reverse Engineering Architect

Published on August 23, 2025

0 views

Signal, Not Noise: Designing Notifications That Inform Without Interrupting ...Because Not Every Message Needs to Shout

Yo! We’re back for another Saturday of learning, rooted in real-world client implementations and global requirements. Are you ready to place another brick in the foundation of our first LEGO-style Business Central masterpiece?

I know I am. Each week, we’ve been stacking modular insights, and we’re getting closer to something truly powerful. You should be excited too HAHAHAHA

This post was technically drafted on Saturday, but I held off publishing while working on our site (yes, it’s coming together!). So better late than never, right? Let’s dive into this week’s #BCSaturdayCodeHacks.

What if I told you this week’s brick is all about the Notification data type? It’s not flashy. It’s not loud. But it’s quietly powerful—especially when used with intention. Let’s explore how to make it work for you.

The Signal We’re Trying to Send (Without the Noise)

Flashback to a past engagement: One of my dev tasks was to notify users when their license was expired, nearly expired, or about to expire. Simple? Technically, yes. But the real magic was in how we delivered it—quiet nudges, not loud alerts. No modal drama. No workflow disruption. Just clean, scoped communication.

That’s where Notification shined. Not as a decoration—but as a modular ritual for respectful UX. It whispered instead of shouted. And that made all the difference.

Then came another gig in Europe (yes, the one with the Shop Floor setup—Sabre’s PrintVis, if you’re curious HAHAHAHA). The challenge? Auto-logout users who forgot to log out, and switch their Role Center. The solution? A session-aware, single-instance codeunit paired with—you guessed it—a scoped Notification to guide the transition without breaking flow.

So that’s my story for this week’s brick. Not flashy. Not so boooooooooooooooooooooring. Just quietly powerful.

Let’s build on that and showcase what we’ve learned in today’s #BCSaturdayCodeHacks. Because every brick counts, and this one’s got an important piece on our LEGO masterpiece.

Introduction: Let’s Talk Notifications in AL

The Notification data type in AL allows developers to send non-blocking messages to the Business Central Web Client. Unlike Message() or Error(), it doesn’t halt execution—it simply informs the user. Notifications are ideal for communicating status, suggestions, or optional actions without disrupting workflow.

They’re especially useful in Role Center pages, background processes, and onboarding flows where clarity matters—but interruption doesn’t.

Use Cases (What’s Worked for Me, Explore Freely)

  • Inform users about the environment where they in e.g. "This is a sandbox environment for test, demo, or development purposes only." Just like Microsoft does HAHAHAHAHAAHAHAHA
  • Inform users of background operations (e.g. “Data sync in progress”)
  • Suggest optional actions (e.g. “You can configure your settings”)
  • Provide contextual feedback during page loads
  • Alert users to non-critical issues or recommendations e.g. like asking the users to activate their license.
  • Enhance startup flows with scoped, non-intrusive messaging

The Not-So-Booooooooooooooooooooooring Coding Example (Starring Me, Myself, and You)

al
procedure ShowOurNotSoBoringWelcomeNotification();
var
    Notify: Notification;
begin
    Notify.Message('Lets learn without the boooooooooooooooooooooooooring!');
    Notify.Scope := NotificationScope::LocalScope;
    Notify.Send();
end;

This sends a local notification—visible only within the current page context. For system-wide visibility, use GlobalScope.

More Code, Less Boredom

al
Notify.SetData('UserType', 'Partner');
Notify.AddAction('OpenSetup', Codeunit::"Not So Boring Codeunit", 'YourNotSoBoringProcedure');
  • AddAction(Caption, CodeunitId, MethodName) → Provides a way for you to add an interactive notification that enables users to respond to or take action on the notification.
  • GetData(Key) → Retrieve metadata
  • HasData(Key) → Check if metadata exists
  • Send() → Display the notification
  • Recall() → Remove a previously sent notification
  • Scope := NotificationScope::LocalScope | GlobalScope → Define visibility

Notification Moves You Should Know

  • .Message() → Sets the notification text
  • .Scope → Defines visibility (Local or Global)
  • .Send() → Displays the notification
  • .AddAction() → Adds a clickable action
  • .SetData() / .GetData() → Passes metadata
  • .Recall() → Removes notification
  • .HasData() → Checks for metadata presence

The Brick in Motion

This demo mirrors the behaviour of a well-known document capture AppSource app. Upon installation, it leverages Codeunit 1430 – Role Center Notification Mgt., just like the technique we explored in last week’s #BCSaturdayCodeHacks, to deliver a subtle, non-intrusive prompt encouraging users to activate their license.

It’s a straightforward showcase: No duplicate detection, No validation layers, Just a clean demonstration of how notification logic can be paired with Role Centre UI pre-render hooks to create a user-friendly onboarding nudge.

Step 1: Subscribe to the Notification Event

Create a codeunit that handles the event subscription. We’ll hook into the OnBeforeShowNotifications event from Role Center Notification Mgt. Codeunit, same as last week’s #BCSaturdayCodeHacks pre-render logic strategy.

codeunit 50108 "JB Event Subscribers"
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Role Center Notification Mgt.", 'OnBeforeShowNotifications', '', false, false)]
    local procedure CodeunitRoleCenterNotificationMgtOnBeforeShowNotifications()
    var
        EventHandler: Codeunit "JB Event Handler";
    begin
        EventHandler.HandleCodeunitRoleCenterNotificationMgtOnBeforeShowNotifications();
    end;
}
Step 2: Create the Handler Codeunit

Create a dedicated handler codeunit that responds to the event raised above. It calls the SendLicenseActivationReminder procedure from our dedicated Notification Management codeunit.

procedure HandleCodeunitRoleCenterNotificationMgtOnBeforeShowNotifications()
var
    NotificationMgt: Codeunit "JB Notification Mgt.";
begin
    NotificationMgt.SendLicenseActivationReminder();
end;
Step 3: Send the License Activation Notification

This procedure handles the sending of a user-facing notification that prompts license activation. It begins by composing a message and defining a clear scope, either LocalScope or GlobalScope, depending on how broadly you want the notification to appear.

Next, it adds three distinct actions using the AddAction method of the Notification data type:

  • Label: The text shown to the user (e.g., Activate now, Remind me in 10 billion days, Don't show this again)
  • Codeunit: The handler codeunit responsible for executing the action logic
  • Function: The specific procedure inside the codeunit that responds to the user’s choice

    Finally, the Send trigger dispatches the notification to the user interface. This mirrors the behavior of the well-known Document Capture AppSource extension, which prompts users to activate their license in a clean, unobtrusive way.

    It’s a simple yet powerful pattern, ideal for onboarding flows, license nudges, or any scenario where you want to guide users without interrupting their workflow.
procedure SendLicenseActivationReminder()
var
    UserNotification: Notification;
    // Keeping the magic of #BCSaturdayCodeHacks alive
    // No LEGO spoilers yet—some bricks are still enchanted
    AppInstalledLbl: Label 'Our Not So Booooooring App has been installed. Would you like to activate it?';
    ActivateNowLbl: Label 'Activate now';
    RemindMeLaterLbl: Label 'Remind me in 10 billion days';
    SuppressNotificationLbl: Label 'Don''t show this again';
begin
    UserNotification.Message(AppInstalledLbl);
    UserNotification.Scope := NotificationScope::LocalScope;

    UserNotification.AddAction(ActivateNowLbl, Codeunit::"JB Notification Handler", 'ActivateLicense');
    UserNotification.AddAction(RemindMeLaterLbl, Codeunit::"JB Notification Handler", 'RemindLater');
    UserNotification.AddAction(SuppressNotificationLbl, Codeunit::"JB Notification Handler", 'DismissNotification');

    UserNotification.Send();
end;
Step 4: Handle the Actions

These procedures live inside the JB Notification Handler codeunit and respond to the user’s choice triggered by the SendLicenseActivationReminder procedure.

procedure ActivateLicense(MyNotification: Notification)
begin
    Message('Activate License action triggered');
end;

procedure RemindLater(MyNotification: Notification)
begin
    Message('Remind Later action triggered');
end;

procedure DismissNotification(MyNotification: Notification)
begin
    Message('Dismiss Notification action triggered');
end;
Step 5: Wrap-Up

That wraps up the core logic. This approach can be extended to support: Onboarding flows, License reminders, Process nudges, Contextual guidance across Role Centers

Feel free to adapt it to your build flow. The Notification data type is quiet, scoped, and powerful—especially when paired with pre-render logic and modular event handling.

Best Practices (I’ve Battle-Tested)

  • Use LocalScope for page-specific messages
  • Reserve GlobalScope for system-wide alerts only
  • Keep messages concise and relevant
  • Modularize notification logic into helper codeunits
  • Use AddAction() to guide users toward next steps
  • Avoid excessive notifications—respect user focus

Things That’ll Bite You If You’re Not Careful

  • Forgetting to call .Send()—the notification won’t appear
  • Using GlobalScope too liberally—can clutter the UI
  • Invalid object references in AddAction()—can cause runtime errors
  • Notifications don’t support rich formatting—stick to plain text
  • Recall() requires tracking the notification ID—plan accordingly

Enough theory, let’s see this beast in action. ✨

Tips That Saved My Sanity

Use SetData() to pass context between modules. For example, tagging a user type or session state allows you to tailor notifications dynamically—without hardcoding logic across pages.

TL;DR & What’s Next

The Notification data type is a powerful tool for improving user experience in Business Central. It enables developers to communicate clearly without interrupting workflows. In future articles, we’ll explore how to build interactive notification registries, implement recall logic, and design multi-user notification flows.

♻️ Repost to support the Microsoft Dynamics 365 Community and follow Jeffrey Bulanadi for clear, technical insights above and beyond Business Central and AL development.

Demo Repository: Explore my GitHub sample showcasing Notification Data Type use-cases and logic in AL: Notification Data Type on GitHub

Helpful References

Notification data type - Business Central | Microsoft Learn
AL Language Reference
Business Central Developer Resources

Tags

#BCSaturdayCodeHacks #ALDevelopment #BusinessCentral #ConsultingLife #Dynamics365 #MSDyn365 #MSDyn365BC #LearningBCNotSoBoringSeries

Share this article

Join the Conversation

Share your thoughts, ask questions, or discuss this article with the community. All comments are moderated to ensure quality discussions.

Loading comments...

Leave a Comment

Your email is secure and will never be published or shared.

Basic HTML tags supported

0/2000 characters

Community Guidelines

  • • Keep discussions professional and on-topic
  • • No spam, self-promotion, or off-topic content
  • • All comments are moderated before publication
  • • Technical questions are especially welcome!