Skip to content

Conversation

@iOvergaard
Copy link
Contributor

@iOvergaard iOvergaard commented Oct 21, 2025

This pull request migrates the preview live update mechanism from a custom WebSocket implementation to SignalR, improving stability and user feedback. It also adds localized notification messages for connection issues. The most significant changes are grouped below.

Benefits:

  • Improves connection stability and reliability by using the official SignalR library
  • Enables SignalR backplane support for load-balanced environments (not possible with the previous custom WebSocket implementation)
  • Better error handling with localized user notifications
  • Proper connection lifecycle management

Migration to SignalR for Preview Live Updates:

  • Replaces the manual WebSocket logic in UmbPreviewContext with a SignalR HubConnection, using HubConnectionBuilder to connect to the /umbraco/PreviewHub endpoint and listen for 'refreshed' events. The connection is now started and stopped using SignalR methods, and event handlers provide better connection lifecycle management. [1] [2] [3] [4] [5]

User Notifications and Localization:

  • Integrates the notification context and localization controller to show user-friendly, localized notifications when the SignalR connection is lost or fails to start. [1] [2]
  • Adds new localized strings for connection errors (connectionFailed, connectionLost) in both Danish (da.ts) and English (en.ts) language files. [1] [2]

Minor Improvements:

  • Refactors URL construction in the preview context for clarity and consistency.
  • Ensures that only one SignalR connection is active at a time (by moving the initiator from the iframeLoaded event to the constructor)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the preview live update mechanism from a custom WebSocket implementation to the SignalR library, improving connection reliability and adding user-friendly error notifications. The change simplifies the connection logic by leveraging SignalR's built-in protocol handling and connection lifecycle management.

Key Changes:

  • Replaced manual WebSocket with SignalR HubConnection for preview updates
  • Added localized notification messages for connection failures and disconnections
  • Moved connection initialization from iframeLoaded to constructor to ensure single connection

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/Umbraco.Web.UI.Client/src/apps/preview/preview.context.ts Replaces WebSocket with SignalR HubConnection, adds notification context and localization controller, moves connection initialization to constructor
src/Umbraco.Web.UI.Client/src/assets/lang/en.ts Adds English localization strings for connection failure and connection lost messages
src/Umbraco.Web.UI.Client/src/assets/lang/da.ts Adds Danish localization strings for connection errors and fixes placement of existing translation key

@iOvergaard
Copy link
Contributor Author

iOvergaard commented Oct 21, 2025

Test Directions

Prerequisites

  • Clean Umbraco installation on the release/17.0 branch
  • At least one document with content that can be edited

Basic Preview Functionality Testing

Test 1: Preview Live Updates (Single Instance)

  1. Log into the Umbraco backoffice
  2. Navigate to a content node and open it for editing
  3. Click the "Preview" button to open the preview window
  4. Make a change to the content (e.g., edit a text field)
  5. Click "Save" (do not publish yet)
  6. Expected: The preview window should automatically refresh and show your saved changes

Test 2: SignalR Connection Notifications

  1. Open the preview window for a content item
  2. Open browser developer tools and check the Network tab
  3. Expected: You should see a successful WebSocket connection to /umbraco/PreviewHub with SignalR negotiation
  4. Stop your Umbraco instance while the preview window is open
  5. Expected: A user-friendly notification should appear indicating the connection was lost

Test 3: Multiple Preview Windows

  1. Open preview windows for 2-3 different content items
  2. Make changes to one of the content items and save
  3. Expected: Only the preview window for the modified content should refresh (check browser console for the correct content key in the refreshed event)

Load Balancing Compatibility Testing (Optional but Important)

This PR enables SignalR backplane compatibility for load-balanced environments. To test:

Prerequisites:

  • Install the IntelliTect.AspNetCore.SignalR.SqlServer NuGet package to Umbraco.Web.UI
  • Set up a SQL Server instance (can use Docker: docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=YourPassword123' -p 1433:1433 --name sqlserver -d mcr.microsoft.com/mssql/server:2022-latest)
  • Create a SignalR backplane database

Setup:

  1. Add multiple hosts to OpenIddict (workaround for testing with multiple ports):

In BackOfficeAuthorizationInitializationMiddleware.cs, add both test ports to the _knownHosts array:

private static readonly string[] _knownHosts =
[
    "https://localhost:44339",
    "https://localhost:44340",
    // ... existing hosts
];
  1. Create the SignalR composer (e.g., SignalRComposer.cs):
using Umbraco.Cms.Core.Composing;

namespace Umbraco.Cms.Web.UI.SignalRLoadBalancing;

public class SignalRComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        var connectionString = "Server=127.0.0.1,1433;Database=SignalRBackplane;User ID=sa;Password=YourPassword123;TrustServerCertificate=True;Encrypt=False;";
        builder.Services.AddSignalR().AddSqlServer(connectionString);
        
        // Enable load balanced isolated cache synchronization
        builder.LoadBalanceIsolatedCaches();
    }
}

Test 4: Cross-Instance Preview Updates

  1. Start two Umbraco instances on different ports (e.g., 44339 and 44340)
  2. Both should connect to the same database and SignalR backplane
  3. Check logs to verify: PreviewHub: SignalR SQL objects installed appears on both instances
  4. Open a preview window on Instance Update README.md #1 (port 44339)
  5. Log into Instance Update README.md #2 (port 44340) and edit the same content
  6. Save the changes on Instance Update README.md #2
  7. Expected: The preview window on Instance Update README.md #1 should receive the refresh notification through the backplane and reload

Key Improvement: This PR enables the preview feature to work correctly with SignalR backplanes in load-balanced environments, which was not possible with the previous custom WebSocket implementation.

Regression Testing

Test 5: Preview with Unpublished Changes

  1. Create a new content item or edit an existing one
  2. Make changes but do NOT publish
  3. Open preview
  4. Expected: Preview shows the unpublished changes
  5. Make additional edits and save (still unpublished)
  6. Expected: Preview automatically updates to show the new changes

Test 6: Browser Console Checks

  1. Open browser developer tools console
  2. Open a preview window
  3. Expected: No JavaScript errors related to SignalR or preview connections
  4. Make content changes and save
  5. Expected: Console should show SignalR messages indicating successful communication (look for refreshed events with content keys)

@leekelleher leekelleher self-requested a review October 21, 2025 12:56
Copy link
Member

@leekelleher leekelleher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested out in a peer review, works as expected in a load balanced set-up. 🚀

@leekelleher leekelleher enabled auto-merge (squash) October 21, 2025 13:01
@leekelleher leekelleher merged commit de5a9ca into release/17.0 Oct 21, 2025
23 checks passed
@leekelleher leekelleher deleted the v17/feature/preview-signalr branch October 21, 2025 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants