Repository: dotnet/aspnetcore
File: src/Components/Server/src/Circuits/RemoteNavigationManager.cs (C#)

Code before:
        Uri = uri;
        HistoryEntryState = state;
        NotifyLocationChanged(intercepted);
    }

    public async ValueTask<bool> HandleLocationChangingAsync(string uri, string? state, bool intercepted)
    {
        return await NotifyLocationChangingAsync(uri, state, intercepted);
    }

    /// <inheritdoc />
    [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(NavigationOptions))]
    protected override void NavigateToCore(string uri, NavigationOptions options)
    {
        Log.RequestingNavigation(_logger, uri, options);

        if (_jsRuntime == null)
        {
            var absoluteUriString = ToAbsoluteUri(uri).AbsoluteUri;
            if (_throwNavigationException)
            {
                throw new NavigationException(absoluteUriString);
            }
            else
            {
                if (!IsInternalUri(absoluteUriString))
                {
                    // it's an external navigation, avoid Uri validation exception
                    BaseUri = GetBaseUriFromAbsoluteUri(absoluteUriString);
                }
                Uri = absoluteUriString;
                NotifyLocationChanged(isInterceptedLink: false);
                return;
            }
        }

        _ = PerformNavigationAsync();

        async Task PerformNavigationAsync()
        {
            try
            {
                var shouldContinueNavigation = await NotifyLocationChangingAsync(uri, options.HistoryEntryState, false);

                if (!shouldContinueNavigation)
                {
                    Log.NavigationCanceled(_logger, uri);
                    return;
                }

                await _jsRuntime.InvokeVoidAsync(Interop.NavigateTo, uri, options);

Review comment (suggestion):
This logic (including `IsInternalUri`, `GetBaseUriFromAbsoluteUri`, `NormalizeBaseUri`) is common for `HttpNavigationManager` and `RemoteNavigationManager`. If we want to consolidate this code, it has to be connected with a public API change (e.g. `protected ServerNavigateTo` in `NavigationManager`).

Code after:

        _jsRuntime = jsRuntime;

        if (_navigationLockStateBeforeJsRuntimeAttached.HasValue)
        {
            _ = SetHasLocationChangingListenersAsync(_navigationLockStateBeforeJsRuntimeAttached.Value);
            _navigationLockStateBeforeJsRuntimeAttached = null;
        }
    }

    public void NotifyLocationChanged(string uri, string state, bool intercepted)
    {
        Log.ReceivedLocationChangedNotification(_logger, uri, intercepted);

        Uri = uri;
        HistoryEntryState = state;
        NotifyLocationChanged(intercepted);
    }

    public async ValueTask<bool> HandleLocationChangingAsync(string uri, string? state, bool intercepted)
    {
        return await NotifyLocationChangingAsync(uri, state, intercepted);
    }

    /// <inheritdoc />
    [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(NavigationOptions))]
    protected override void NavigateToCore(string uri, NavigationOptions options)
    {
        Log.RequestingNavigation(_logger, uri, options);

        if (_jsRuntime == null)
        {
            var absoluteUriString = ToAbsoluteUri(uri).AbsoluteUri;
            if (_throwNavigationException)
            {
                throw new NavigationException(absoluteUriString);
            }
            if (_onNavigateTo == null)
            {
                throw new InvalidOperationException($"'{GetType().Name}' method for endpoint-based navigation has not been initialized.");
            }
            _ = _onNavigateTo(absoluteUriString);
            return;
        }

        _ = PerformNavigationAsync();

        async Task PerformNavigationAsync()
        {
            try
            {