Implementing Real-Time Notifications in Power Pages Using Azure SignalR Service

Real-time notifications can transform a Power Pages portal from static to dynamic, instantly alerting users to critical updates like status changes, new messages, or system alerts without forcing them to refresh the page.

Whether it’s notifying a customer about an order update or alerting an employee to a new task, Azure SignalR Service makes this possible with low-latency, scalable messaging. By combining SignalR with Azure Functions, Dataverse events, and client-side JavaScript, you can push updates to connected users seamlessly.

Lets explore the architecture, walk through triggering Functions from Dataverse, broadcasting messages via SignalR, and handling them in Power Pages, complete with code to bring it to life.

Why Real-Time Notifications Matter

Power Pages excels at delivering data-driven portals, but polling for updates (like refreshing a dashboard) feels clunky and wastes resources. Real-time notifications fix that, creating an engaging experience where users get instant feedback.

Azure SignalR Service is the perfect tool—it’s a managed WebSocket solution that handles the complexity of real-time communication, letting you focus on what to send and when.

Pair it with Power Pages’ Dataverse backbone and Azure Functions for event-driven logic, and you’ve got a robust setup for pushing updates to the right users at the right time.

Architectural Pattern for Real-Time Updates

The setup follows a clear flow: a Dataverse event—like a record update—triggers an Azure Function, which sends a message to Azure SignalR Service, which then broadcasts it to connected Power Pages users.

Client-side JavaScript in the portal listens for these messages and updates the UI. For example, when a support ticket’s status changes to “Resolved,” the assigned customer gets a notification instantly. The pieces are:

  • Dataverse Event: A record change (create, update) in a table like incident.
  • Azure Function: Handles the event, formats the message, and talks to SignalR.
  • Azure SignalR Service: Broadcasts the message to clients.
  • Power Pages Client: JavaScript listens for messages and updates the page.

This keeps the portal lightweight while SignalR scales to thousands of users effortlessly.

Triggering Azure Functions from Dataverse Events

First, you need to catch Dataverse events and relay them to an Azure Function. You can use a custom plugin for precise control or Power Automate for low-code simplicity. Let’s say you want to notify users when an incident record’s status changes.

With Power Automate, create a flow triggered by “When a record is updated” for the incident table, filtering for statuscode changes.

Add an HTTP action to call an Azure Function. Here’s a sample Function in C# that processes the event:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;

public class IncidentUpdateTrigger
{
    private readonly HttpClient _client;

    public IncidentUpdateTrigger(IHttpClientFactory factory)
    {
        _client = factory.CreateClient();
    }

    [Function("IncidentUpdate")]
    public async Task Run(
        [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
    {
        string body = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(body);
        string incidentId = data?.incidentid;
        string status = data?.statuscode_label;

        // Send to SignalR
        await _client.PostAsJsonAsync(
            "https://your-signalr-instance.service.signalr.net/api/v1/hubs/notify",
            new { incidentId, status, message = $"Ticket {incidentId} is now {status}" },
            new Dictionary<string, string> { { "x-ms-signalr-user-id", incidentId } }
        );
    }
}

Deploy this to Azure, secure it with a function key, and note the URL. In your flow, pass the incident data (ID, status) to the Function’s endpoint.

Alternatively, a plugin could fire on the incident update, calling the Function via HTTP—use the Dataverse SDK’s IPluginExecutionContext to grab the record details. Test by updating a ticket and checking the Function’s logs in Azure.

Broadcasting Messages with Azure SignalR Service

Azure SignalR Service handles the real-time magic, pushing messages to clients via WebSockets. Create a SignalR instance in Azure (Developer tier works for small portals).

Enable serverless mode for simplicity, as you’ll use Functions to send messages. Grab the connection string from the SignalR resource’s Keys tab.

Update the Function to connect to SignalR. If you’re using the SignalR output binding, modify the code:

[Function("IncidentUpdate")]
[SignalROutput(HubName = "notify")]
public async Task<SignalRMessageAction> Run(
    [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
{
    string body = await new StreamReader(req.Body).ReadToEndAsync();
    dynamic data = JsonConvert.DeserializeObject(body);
    string incidentId = data?.incidentid;
    string status = data?.statuscode_label;

    return new SignalRMessageAction("newNotification")
    {
        Arguments = new[] { new { incidentId, status, message = $"Ticket {incidentId} is now {status}" } },
        UserId = incidentId // Target specific user
    };
}

This targets the message to a specific user (tied to incidentId). Deploy and test—update a ticket, and verify SignalR logs show the message being sent.

Handling Messages in Power Pages with JavaScript

On the Power Pages side, add client-side JavaScript to listen for SignalR messages and update the UI. In the portal, create a Web Template or inject code into a page. First, include the SignalR client library and connect to your hub:

<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.min.js"></script>
<script>
  const connection = new signalR.HubConnectionBuilder()
    .withUrl("https://your-signalr-instance.service.signalr.net/client/?hub=notify", {
      accessTokenFactory: async () => {
        // Fetch token from your Function or endpoint
        const response = await fetch("/api/get-signalr-token");
        return await response.text();
      }
    })
    .build();

  connection.on("newNotification", (data) => {
    const notification = document.createElement("div");
    notification.className = "alert alert-info";
    notification.textContent = data.message;
    document.getElementById("notifications").prepend(notification);
    setTimeout(() => notification.remove(), 5000); // Auto-dismiss
  });

  connection.start().catch(err => console.error(err));
</script>
<div id="notifications"></div>

The /api/get-signalr-token endpoint could be another Azure Function that negotiates the SignalR connection, secured with Azure AD or a portal-specific key.

In Power Pages, map the UserId to the logged-in user’s Dataverse contact ID (via Liquid: {{ user.id }}). Test by updating a ticket—your portal should show a pop-up like “Ticket 123 is now Resolved.”

Security and Scalability Tips

Security is critical. Secure your Function with keys or Azure AD, and use Managed Identity for SignalR to avoid hardcoding connection strings. On the client, ensure only authenticated users access the SignalR hub—validate tokens server-side.

For scalability, SignalR’s managed service handles thousands of connections, but optimize messages—send minimal data (e.g., { id, status }) to reduce bandwidth. Monitor Azure diagnostics for connection drops or latency spikes, and test under load with tools like JMeter.

Cost Considerations

Azure SignalR’s Developer tier is free for small-scale use (20 concurrent connections), but Standard tier ($1.61/day for 1 unit) supports more users—estimate based on your portal’s audience.

Functions are cheap on the consumption plan ($0.20/million executions), but heavy notifications could nudge costs up. Power Pages licensing (per user or capacity) applies separately. Check Azure’s pricing calculator if your portal scales rapidly.

Building a Responsive Portal

Real-time notifications with Azure SignalR Service make Power Pages feel alive, keeping users informed without manual refreshes.

By triggering Functions from Dataverse, broadcasting via SignalR, and catching messages client-side, you create a slick, responsive experience.

Secure it, test it, and monitor costs, and you’ll turn your portal into a hub that users rely on. It’s not just tech—it’s a way to keep everyone connected instantly.

If you have any questions, hit me up on linkedin!

Share the Post: