diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Branding/UrlHelperBrandingExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Branding/UrlHelperBrandingExtensions.cs
new file mode 100644
index 0000000000..f652dac543
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Branding/UrlHelperBrandingExtensions.cs
@@ -0,0 +1,40 @@
+using System;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Branding;
+
+public static class UrlHelperBrandingExtensions
+{
+ ///
+ /// Resolves a branding url of for the current request.
+ /// "logo.svg", "/logo.svg" and "~/logo.svg" all mean the same application relative url and keep working
+ /// under a non-root .
+ /// External urls ("http://", "https://" and "//host/") are returned as they are.
+ /// Returns null when is null or white space.
+ ///
+ public static string? ResolveBrandingUrl(this IUrlHelper urlHelper, string? url)
+ {
+ if (url.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+
+ if (IsExternalUrl(url!))
+ {
+ return url;
+ }
+
+ var applicationRelativeUrl = url!.StartsWith("~/", StringComparison.Ordinal)
+ ? url
+ : "~/" + url.TrimStart('/');
+
+ return urlHelper.Content(applicationRelativeUrl);
+ }
+
+ private static bool IsExternalUrl(string url)
+ {
+ return url.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
+ || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
+ || url.StartsWith("//", StringComparison.Ordinal);
+ }
+}
diff --git a/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/BrandingProviderLogoExtensions.cs b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/BrandingProviderLogoExtensions.cs
new file mode 100644
index 0000000000..6661f17c73
--- /dev/null
+++ b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/BrandingProviderLogoExtensions.cs
@@ -0,0 +1,20 @@
+namespace Volo.Abp.Ui.Branding;
+
+public static class BrandingProviderLogoExtensions
+{
+ ///
+ /// Returns the compact logo of the branding provider on white background when available; otherwise, null.
+ ///
+ public static string? GetLogoIconUrlOrNull(this IBrandingProvider brandingProvider)
+ {
+ return (brandingProvider as IBrandingLogoProvider)?.LogoIconUrl;
+ }
+
+ ///
+ /// Returns the compact logo of the branding provider on dark background when available; otherwise, null.
+ ///
+ public static string? GetLogoIconReverseUrlOrNull(this IBrandingProvider brandingProvider)
+ {
+ return (brandingProvider as IBrandingLogoProvider)?.LogoIconReverseUrl;
+ }
+}
diff --git a/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/DefaultBrandingProvider.cs b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/DefaultBrandingProvider.cs
index fcb1a7545e..aa386c593e 100644
--- a/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/DefaultBrandingProvider.cs
+++ b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/DefaultBrandingProvider.cs
@@ -2,11 +2,15 @@
namespace Volo.Abp.Ui.Branding;
-public class DefaultBrandingProvider : IBrandingProvider, ITransientDependency
+public class DefaultBrandingProvider : IBrandingProvider, IBrandingLogoProvider, ITransientDependency
{
public virtual string AppName => "MyApplication";
public virtual string? LogoUrl => null;
public virtual string? LogoReverseUrl => null;
+
+ public virtual string? LogoIconUrl => null;
+
+ public virtual string? LogoIconReverseUrl => null;
}
diff --git a/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/IBrandingLogoProvider.cs b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/IBrandingLogoProvider.cs
new file mode 100644
index 0000000000..4cb38cd3a8
--- /dev/null
+++ b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/IBrandingLogoProvider.cs
@@ -0,0 +1,18 @@
+namespace Volo.Abp.Ui.Branding;
+
+///
+/// Optionally implemented by an to provide a compact logo,
+/// used where the full logo does not fit, like a collapsed menu.
+///
+public interface IBrandingLogoProvider
+{
+ ///
+ /// Compact logo on white background
+ ///
+ string? LogoIconUrl { get; }
+
+ ///
+ /// Compact logo on dark background
+ ///
+ string? LogoIconReverseUrl { get; }
+}
diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Brand/Default.cshtml b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Brand/Default.cshtml
index 04a4f81c71..fb15426730 100644
--- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Brand/Default.cshtml
+++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Brand/Default.cshtml
@@ -1,9 +1,10 @@
@using Volo.Abp.Ui.Branding
+@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Branding
@inject IBrandingProvider BrandingProvider
@if (!BrandingProvider.LogoUrl.IsNullOrWhiteSpace())
{
-
+
}
@BrandingProvider.AppName
diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml
index 5dc1619ec8..75c57ec834 100644
--- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml
+++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml
@@ -12,6 +12,7 @@
@using Volo.Abp.MultiTenancy
@using Volo.Abp.Localization
@using Volo.Abp.Ui.Branding
+@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Branding
@using Volo.Abp.Ui.LayoutHooks
@inject IBrandingProvider BrandingProvider
@inject IOptions MultiTenancyOptions
@@ -64,7 +65,7 @@
-

+
@BrandingProvider.AppName
@if (MultiTenancyOptions.Value.IsEnabled &&