diff --git a/Wave/Components/UserLinkComponent.razor b/Wave/Components/UserLinkComponent.razor
index b4738e4..ea98ec6 100644
--- a/Wave/Components/UserLinkComponent.razor
+++ b/Wave/Components/UserLinkComponent.razor
@@ -1,7 +1,8 @@
@using Wave.Data
+@using System.Net
-
+
@(Link.Url.Host.LastIndexOf('.') > -1 ? Link.Url.Host[..Link.Url.Host.LastIndexOf('.')] : Link.Url.Host)
diff --git a/Wave/Controllers/ApiProxy.cs b/Wave/Controllers/ApiProxy.cs
new file mode 100644
index 0000000..e562f0c
--- /dev/null
+++ b/Wave/Controllers/ApiProxy.cs
@@ -0,0 +1,31 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace Wave.Controllers;
+
+[ApiController]
+[Route("/api/proxy")]
+public class ApiProxy(HttpClient client) : ControllerBase {
+ private HttpClient Client { get; } = client;
+
+ [Route("favicon/{host}")]
+ [Produces("image/x-icon")]
+ [ResponseCache(Duration = 60*60*24*30, Location = ResponseCacheLocation.Any)]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ public async Task GetFavicon(string host, [FromQuery] int size = 32) {
+ var response = await DoProxy("https://favicone.com/" + host + "?s=" + size);
+
+ if (!response.IsSuccessStatusCode) {
+ Response.StatusCode = StatusCodes.Status404NotFound;
+ return;
+ }
+
+ byte[] data = await response.Content.ReadAsByteArrayAsync();
+ await Response.BodyWriter.WriteAsync(data);
+ }
+
+
+ private async Task DoProxy(string url) {
+ return await Client.SendAsync(new HttpRequestMessage(HttpMethod.Get, url));
+ }
+}
\ No newline at end of file
diff --git a/Wave/Program.cs b/Wave/Program.cs
index 17d483f..233f6d3 100644
--- a/Wave/Program.cs
+++ b/Wave/Program.cs
@@ -101,6 +101,7 @@
options.ResourcesPath = "Resources";
});
builder.Services.AddScoped();
+builder.Services.AddHttpClient();
builder.Services.Configure(builder.Configuration.GetSection(nameof(Customization)));
builder.Services.AddCascadingValue("TitlePrefix",