diff --git a/Directory.Packages.props b/Directory.Packages.props
index 182f7e19..30cf682f 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -40,6 +40,7 @@
     
     
     
+    
     
     
   
diff --git a/EssentialCSharp.Web.Tests/RouteConfigurationServiceTests.cs b/EssentialCSharp.Web.Tests/RouteConfigurationServiceTests.cs
new file mode 100644
index 00000000..9280e3fd
--- /dev/null
+++ b/EssentialCSharp.Web.Tests/RouteConfigurationServiceTests.cs
@@ -0,0 +1,35 @@
+using EssentialCSharp.Web.Services;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace EssentialCSharp.Web.Tests;
+
+public class RouteConfigurationServiceTests : IClassFixture
+{
+    private readonly WebApplicationFactory _Factory;
+
+    public RouteConfigurationServiceTests(WebApplicationFactory factory)
+    {
+        _Factory = factory;
+    }
+
+    [Fact]
+    public void GetStaticRoutes_ShouldReturnExpectedRoutes()
+    {
+        // Act
+        var routes = _Factory.InServiceScope(serviceProvider =>
+        {
+            var routeConfigurationService = serviceProvider.GetRequiredService();
+            return routeConfigurationService.GetStaticRoutes().ToList();
+        });
+
+        // Assert
+        Assert.NotEmpty(routes);
+
+        // Check for expected routes from the HomeController
+        Assert.Contains("home", routes);
+        Assert.Contains("about", routes);
+        Assert.Contains("guidelines", routes);
+        Assert.Contains("announcements", routes);
+        Assert.Contains("termsofservice", routes);
+    }
+}
diff --git a/EssentialCSharp.Web.Tests/SitemapXmlHelpersTests.cs b/EssentialCSharp.Web.Tests/SitemapXmlHelpersTests.cs
new file mode 100644
index 00000000..6c801d1e
--- /dev/null
+++ b/EssentialCSharp.Web.Tests/SitemapXmlHelpersTests.cs
@@ -0,0 +1,259 @@
+using System.Globalization;
+using DotnetSitemapGenerator;
+using EssentialCSharp.Web.Helpers;
+using EssentialCSharp.Web.Services;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace EssentialCSharp.Web.Tests;
+
+public class SitemapXmlHelpersTests : IClassFixture
+{
+    private readonly WebApplicationFactory _Factory;
+
+    public SitemapXmlHelpersTests(WebApplicationFactory factory)
+    {
+        _Factory = factory;
+    }
+
+    [Fact]
+    public void EnsureSitemapHealthy_WithValidSiteMappings_DoesNotThrow()
+    {
+        // Arrange
+        var siteMappings = new List
+        {
+            CreateSiteMapping(1, 1, true),
+            CreateSiteMapping(1, 2, true),
+            CreateSiteMapping(2, 1, true)
+        };
+
+        // Act & Assert
+        var exception = Record.Exception(() => SitemapXmlHelpers.EnsureSitemapHealthy(siteMappings));
+        Assert.Null(exception);
+    }
+
+    [Fact]
+    public void EnsureSitemapHealthy_WithMultipleCanonicalLinksForSamePage_ThrowsException()
+    {
+        // Arrange - Two mappings for the same chapter/page both marked as canonical
+        var siteMappings = new List
+        {
+            CreateSiteMapping(1, 1, true),
+            CreateSiteMapping(1, 1, true) // Same chapter/page, also canonical
+        };
+
+        // Act & Assert
+        var exception = Assert.Throws(() =>
+            SitemapXmlHelpers.EnsureSitemapHealthy(siteMappings));
+
+        Assert.Contains("Chapter 1, Page 1", exception.Message);
+        Assert.Contains("more than one canonical link", exception.Message);
+    }
+
+    [Fact]
+    public void EnsureSitemapHealthy_WithNoCanonicalLinksForPage_ThrowsException()
+    {
+        // Arrange - No mappings marked as canonical for this page
+        var siteMappings = new List
+        {
+            CreateSiteMapping(1, 1, false),
+            CreateSiteMapping(1, 1, false) // Same chapter/page, neither canonical
+        };
+
+        // Act & Assert
+        var exception = Assert.Throws(() =>
+            SitemapXmlHelpers.EnsureSitemapHealthy(siteMappings));
+
+        Assert.Contains("Chapter 1, Page 1", exception.Message);
+    }
+
+    [Fact]
+    public void GenerateSitemapXml_DoesNotIncludeIdentityRoutes()
+    {
+        // Arrange
+        var tempDir = new DirectoryInfo(Path.GetTempPath());
+        var siteMappings = new List { CreateSiteMapping(1, 1, true) };
+        var baseUrl = "https://test.example.com/";
+
+        // Act & Assert
+        var routeConfigurationService = _Factory.Services.GetRequiredService();
+        SitemapXmlHelpers.GenerateSitemapXml(
+            tempDir,
+            siteMappings,
+            routeConfigurationService,
+            baseUrl,
+            out var nodes);
+
+        var allUrls = nodes.Select(n => n.Url).ToList();
+
+        // Verify no Identity routes are included
+        Assert.DoesNotContain(allUrls, url => url.Contains("Identity", StringComparison.OrdinalIgnoreCase));
+        Assert.DoesNotContain(allUrls, url => url.Contains("Account", StringComparison.OrdinalIgnoreCase));
+
+        // But verify that expected routes are included
+        Assert.Contains(allUrls, url => url.Contains("/home", StringComparison.OrdinalIgnoreCase));
+        Assert.Contains(allUrls, url => url.Contains("/about", StringComparison.OrdinalIgnoreCase));
+    }
+
+    [Fact]
+    public void GenerateSitemapXml_IncludesBaseUrl()
+    {
+        // Arrange
+        var tempDir = new DirectoryInfo(Path.GetTempPath());
+        var siteMappings = new List();
+        var baseUrl = "https://test.example.com/";
+
+        // Act & Assert
+        var routeConfigurationService = _Factory.Services.GetRequiredService();
+        SitemapXmlHelpers.GenerateSitemapXml(
+            tempDir,
+            siteMappings,
+            routeConfigurationService,
+            baseUrl,
+            out var nodes);
+
+        Assert.Contains(nodes, node => node.Url == baseUrl);
+
+        // Verify the root URL has highest priority
+        var rootNode = nodes.First(node => node.Url == baseUrl);
+        Assert.Equal(1.0M, rootNode.Priority);
+        Assert.Equal(ChangeFrequency.Daily, rootNode.ChangeFrequency);
+    }
+
+    [Fact]
+    public void GenerateSitemapXml_IncludesSiteMappingsMarkedForXml()
+    {
+        // Arrange
+        var tempDir = new DirectoryInfo(Path.GetTempPath());
+        var baseUrl = "https://test.example.com/";
+
+        var siteMappings = new List
+        {
+            CreateSiteMapping(1, 1, true, "test-page-1"),
+            CreateSiteMapping(1, 2, false, "test-page-2"), // Not included in XML
+            CreateSiteMapping(2, 1, true, "test-page-3")
+        };
+
+        // Act & Assert
+        var routeConfigurationService = _Factory.Services.GetRequiredService();
+        SitemapXmlHelpers.GenerateSitemapXml(
+            tempDir,
+            siteMappings,
+            routeConfigurationService,
+            baseUrl,
+            out var nodes);
+
+        var allUrls = nodes.Select(n => n.Url).ToList();
+
+        Assert.Contains(allUrls, url => url.Contains("test-page-1"));
+        Assert.DoesNotContain(allUrls, url => url.Contains("test-page-2")); // Not marked for XML
+        Assert.Contains(allUrls, url => url.Contains("test-page-3"));
+    }
+
+    [Fact]
+    public void GenerateSitemapXml_DoesNotIncludeIndexRoutes()
+    {
+        // Arrange
+        var tempDir = new DirectoryInfo(Path.GetTempPath());
+        var siteMappings = new List();
+        var baseUrl = "https://test.example.com/";
+
+        // Act & Assert
+        var routeConfigurationService = _Factory.Services.GetRequiredService();
+        SitemapXmlHelpers.GenerateSitemapXml(
+            tempDir,
+            siteMappings,
+            routeConfigurationService,
+            baseUrl,
+            out var nodes);
+
+        var allUrls = nodes.Select(n => n.Url).ToList();
+
+        // Should not include Index action routes (they're the default)
+        Assert.DoesNotContain(allUrls, url => url.Contains("/Index", StringComparison.OrdinalIgnoreCase));
+    }
+
+    [Fact]
+    public void GenerateSitemapXml_DoesNotIncludeErrorRoutes()
+    {
+        // Arrange
+        var tempDir = new DirectoryInfo(Path.GetTempPath());
+        var siteMappings = new List();
+        var baseUrl = "https://test.example.com/";
+
+        // Act & Assert
+        var routeConfigurationService = _Factory.Services.GetRequiredService();
+        SitemapXmlHelpers.GenerateSitemapXml(
+            tempDir,
+            siteMappings,
+            routeConfigurationService,
+            baseUrl,
+            out var nodes);
+
+        var allUrls = nodes.Select(n => n.Url).ToList();
+
+        // Should not include Error action routes
+        Assert.DoesNotContain(allUrls, url => url.Contains("/Error", StringComparison.OrdinalIgnoreCase));
+    }
+
+    [Fact]
+    public void GenerateAndSerializeSitemapXml_CreatesFileSuccessfully()
+    {
+        // Arrange
+        var logger = _Factory.Services.GetRequiredService>();
+        var tempDir = new DirectoryInfo(Path.GetTempPath());
+        var siteMappings = new List { CreateSiteMapping(1, 1, true) };
+        var baseUrl = "https://test.example.com/";
+
+        // Clean up any existing file
+        var expectedXmlPath = Path.Combine(tempDir.FullName, "sitemap.xml");
+        File.Delete(expectedXmlPath);
+
+        try
+        {
+            // Act
+            var routeConfigurationService = _Factory.Services.GetRequiredService();
+            SitemapXmlHelpers.GenerateAndSerializeSitemapXml(
+                tempDir,
+                siteMappings,
+                logger,
+                routeConfigurationService,
+                baseUrl);
+
+            // Assert
+            Assert.True(File.Exists(expectedXmlPath));
+
+            var xmlContent = File.ReadAllText(expectedXmlPath);
+            Assert.Contains("
+public sealed class WebApplicationFactory : WebApplicationFactory
 {
     private static string SqlConnectionString => $"DataSource=file:{Guid.NewGuid()}?mode=memory&cache=shared";
     private SqliteConnection? _Connection;
@@ -42,6 +42,30 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
         });
     }
 
+    /// 
+    /// Executes an action within a service scope, handling scope creation and cleanup automatically.
+    /// 
+    /// The return type of the action
+    /// The action to execute with the scoped service provider
+    /// The result of the action
+    public T InServiceScope(Func action)
+    {
+        var factory = Services.GetRequiredService();
+        using var scope = factory.CreateScope();
+        return action(scope.ServiceProvider);
+    }
+
+    /// 
+    /// Executes an action within a service scope, handling scope creation and cleanup automatically.
+    /// 
+    /// The action to execute with the scoped service provider
+    public void InServiceScope(Action action)
+    {
+        var factory = Services.GetRequiredService();
+        using var scope = factory.CreateScope();
+        action(scope.ServiceProvider);
+    }
+
     protected override void Dispose(bool disposing)
     {
         base.Dispose(disposing);
diff --git a/EssentialCSharp.Web/Controllers/BaseController.cs b/EssentialCSharp.Web/Controllers/BaseController.cs
new file mode 100644
index 00000000..f1bdbb89
--- /dev/null
+++ b/EssentialCSharp.Web/Controllers/BaseController.cs
@@ -0,0 +1,22 @@
+using EssentialCSharp.Web.Services;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+
+namespace EssentialCSharp.Web.Controllers;
+
+public abstract class BaseController : Controller
+{
+    private readonly IRouteConfigurationService _RouteConfigurationService;
+
+    protected BaseController(IRouteConfigurationService routeConfigurationService)
+    {
+        _RouteConfigurationService = routeConfigurationService;
+    }
+
+    public override void OnActionExecuting(ActionExecutingContext context)
+    {
+        // Automatically add static routes to all views
+        ViewBag.StaticRoutes = System.Text.Json.JsonSerializer.Serialize(_RouteConfigurationService.GetStaticRoutes());
+        base.OnActionExecuting(context);
+    }
+}
diff --git a/EssentialCSharp.Web/EssentialCSharp.Web.csproj b/EssentialCSharp.Web/EssentialCSharp.Web.csproj
index 4cb85e02..2c2b6426 100644
--- a/EssentialCSharp.Web/EssentialCSharp.Web.csproj
+++ b/EssentialCSharp.Web/EssentialCSharp.Web.csproj
@@ -35,6 +35,7 @@
     
     
     
+    
   
   
     
diff --git a/EssentialCSharp.Web/Helpers/SitemapXmlHelpers.cs b/EssentialCSharp.Web/Helpers/SitemapXmlHelpers.cs
new file mode 100644
index 00000000..0247b6f5
--- /dev/null
+++ b/EssentialCSharp.Web/Helpers/SitemapXmlHelpers.cs
@@ -0,0 +1,100 @@
+using DotnetSitemapGenerator;
+using DotnetSitemapGenerator.Serialization;
+using EssentialCSharp.Web.Services;
+
+namespace EssentialCSharp.Web.Helpers;
+
+public static class SitemapXmlHelpers
+{
+    public static void EnsureSitemapHealthy(List siteMappings)
+    {
+        var groups = siteMappings.GroupBy(item => new { item.ChapterNumber, item.PageNumber });
+        foreach (var group in groups)
+        {
+            var count = group.Count(item => item.IncludeInSitemapXml);
+            if (count != 1)
+            {
+                throw new InvalidOperationException($"Sitemap error: Chapter {group.Key.ChapterNumber}, Page {group.Key.PageNumber} has more than one canonical link, or none");
+            }
+        }
+    }
+
+    public static void GenerateAndSerializeSitemapXml(DirectoryInfo wwwrootDirectory, List siteMappings, ILogger logger, IRouteConfigurationService routeConfigurationService, string baseUrl)
+    {
+        GenerateSitemapXml(wwwrootDirectory, siteMappings, routeConfigurationService, baseUrl, out List nodes);
+        XmlSerializer sitemapProvider = new();
+        var xmlPath = Path.Combine(wwwrootDirectory.FullName, "sitemap.xml");
+        sitemapProvider.Serialize(new SitemapModel(nodes), xmlPath, true);
+        logger.LogInformation("sitemap.xml successfully written to {XmlPath}", xmlPath);
+    }
+
+    public static void GenerateSitemapXml(DirectoryInfo wwwrootDirectory, List siteMappings, IRouteConfigurationService routeConfigurationService, string baseUrl, out List nodes)
+    {
+        DateTime newDateTime = DateTime.UtcNow;
+
+        // Routes should end up with leading slash
+        baseUrl = baseUrl.TrimEnd('/');
+
+        // Start with the root URL
+        nodes = new() {
+            new($"{baseUrl}/")
+            {
+                LastModificationDate = newDateTime,
+                ChangeFrequency = ChangeFrequency.Daily,
+                Priority = 1.0M
+            }
+        };
+
+        // Add routes dynamically discovered from controllers
+        var allRoutes = routeConfigurationService.GetStaticRoutes();
+        var controllerRoutes = allRoutes
+            .Where(route => !route.Contains("error", StringComparison.OrdinalIgnoreCase)) // Skip Error actions for sitemap
+            .Where(route => !route.Contains("index", StringComparison.OrdinalIgnoreCase)) // Skip Index actions for sitemap
+            .Where(route => !route.Contains("identity", StringComparison.OrdinalIgnoreCase)) // Skip Identity actions for sitemap
+        // All routes should have leading slash
+            .Select(route => $"/{route}") // Add leading slash for sitemap URLs
+            .ToList();
+
+        foreach (var route in controllerRoutes)
+        {
+            nodes.Add(new($"{baseUrl}{route}")
+            {
+                LastModificationDate = newDateTime,
+                ChangeFrequency = GetChangeFrequencyForRoute(route),
+                Priority = GetPriorityForRoute(route)
+            });
+        }
+
+        // Add site mappings from content
+        nodes.AddRange(siteMappings.Where(item => item.IncludeInSitemapXml).Select(siteMapping => new($"{baseUrl.TrimEnd('/')}/{siteMapping.Keys.First()}")
+        {
+            LastModificationDate = newDateTime,
+            ChangeFrequency = ChangeFrequency.Daily,
+            Priority = 0.8M
+        }));
+    }
+
+    private static ChangeFrequency GetChangeFrequencyForRoute(string route)
+    {
+        return route.ToLowerInvariant() switch
+        {
+            "/termsofservice" => ChangeFrequency.Yearly,
+            "/announcements" => ChangeFrequency.Monthly,
+            "/guidelines" => ChangeFrequency.Monthly,
+            _ => ChangeFrequency.Monthly
+        };
+    }
+
+    private static decimal GetPriorityForRoute(string route)
+    {
+        return route.ToLowerInvariant() switch
+        {
+            "/home" => 0.5M,
+            "/about" => 0.5M,
+            "/announcements" => 0.5M,
+            "/guidelines" => 0.9M,
+            "/termsofservice" => 0.2M,
+            _ => 0.5M
+        };
+    }
+}
diff --git a/EssentialCSharp.Web/Program.cs b/EssentialCSharp.Web/Program.cs
index 56f97373..f0f807b6 100644
--- a/EssentialCSharp.Web/Program.cs
+++ b/EssentialCSharp.Web/Program.cs
@@ -3,6 +3,7 @@
 using EssentialCSharp.Web.Areas.Identity.Services.PasswordValidators;
 using EssentialCSharp.Web.Data;
 using EssentialCSharp.Web.Extensions;
+using EssentialCSharp.Web.Helpers;
 using EssentialCSharp.Web.Middleware;
 using EssentialCSharp.Web.Services;
 using EssentialCSharp.Web.Services.Referrals;
@@ -41,7 +42,7 @@ private static void Main(string[] args)
         // Create a temporary logger for startup logging
         using var loggerFactory = LoggerFactory.Create(loggingBuilder =>
             loggingBuilder.AddConsole().SetMinimumLevel(LogLevel.Information));
-        var logger = loggerFactory.CreateLogger();
+        var initialLogger = loggerFactory.CreateLogger();
 
         if (!builder.Environment.IsDevelopment())
         {
@@ -51,17 +52,17 @@ private static void Main(string[] args)
 
             if (!string.IsNullOrEmpty(appInsightsConnectionString))
             {
-            builder.Services.AddOpenTelemetry().UseAzureMonitor(
-                options =>
-                {
-                    options.ConnectionString = appInsightsConnectionString;
-                });
+                builder.Services.AddOpenTelemetry().UseAzureMonitor(
+                    options =>
+                    {
+                        options.ConnectionString = appInsightsConnectionString;
+                    });
                 builder.Services.AddApplicationInsightsTelemetry();
                 builder.Services.AddServiceProfiler();
             }
             else
             {
-                logger.LogWarning("Application Insights connection string not found. Telemetry collection will be disabled.");
+                initialLogger.LogWarning("Application Insights connection string not found. Telemetry collection will be disabled.");
             }
         }
 
@@ -146,6 +147,7 @@ private static void Main(string[] args)
         builder.Services.AddRazorPages();
         builder.Services.AddCaptchaService(builder.Configuration.GetSection(CaptchaOptions.CaptchaSender));
         builder.Services.AddSingleton();
+        builder.Services.AddSingleton();
         builder.Services.AddHostedService();
         builder.Services.AddScoped();
 
@@ -182,7 +184,6 @@ private static void Main(string[] args)
 
 
         WebApplication app = builder.Build();
-
         // Configure the HTTP request pipeline.
         if (!app.Environment.IsDevelopment())
         {
@@ -215,6 +216,29 @@ private static void Main(string[] args)
 
         app.MapFallbackToController("Index", "Home");
 
+        // Generate sitemap.xml at startup
+        var wwwrootDirectory = new DirectoryInfo(app.Environment.WebRootPath);
+        var siteMappingService = app.Services.GetRequiredService();
+        var logger = app.Services.GetRequiredService>();
+
+        // Extract base URL from configuration
+        var baseUrl = configuration.GetSection("SiteSettings")["BaseUrl"] ?? "https://essentialcsharp.com";
+
+        try
+        {
+            // Create a scope to resolve scoped services
+            var routeConfigurationService = app.Services.GetRequiredService();
+
+            SitemapXmlHelpers.EnsureSitemapHealthy(siteMappingService.SiteMappings.ToList());
+            SitemapXmlHelpers.GenerateAndSerializeSitemapXml(wwwrootDirectory, siteMappingService.SiteMappings.ToList(), logger, routeConfigurationService, baseUrl);
+            logger.LogInformation("Sitemap.xml generation completed successfully during application startup");
+        }
+        catch (Exception ex)
+        {
+            logger.LogError(ex, "Failed to generate sitemap.xml during application startup");
+            // Continue startup even if sitemap generation fails
+        }
+
         app.Run();
     }
 }
diff --git a/EssentialCSharp.Web/Services/IRouteConfigurationService.cs b/EssentialCSharp.Web/Services/IRouteConfigurationService.cs
new file mode 100644
index 00000000..b22b1f0a
--- /dev/null
+++ b/EssentialCSharp.Web/Services/IRouteConfigurationService.cs
@@ -0,0 +1,6 @@
+namespace EssentialCSharp.Web.Services;
+
+public interface IRouteConfigurationService
+{
+    IReadOnlySet GetStaticRoutes();
+}
diff --git a/EssentialCSharp.Web/Services/RouteConfigurationService.cs b/EssentialCSharp.Web/Services/RouteConfigurationService.cs
new file mode 100644
index 00000000..0429d6b0
--- /dev/null
+++ b/EssentialCSharp.Web/Services/RouteConfigurationService.cs
@@ -0,0 +1,63 @@
+using Microsoft.AspNetCore.Mvc.Infrastructure;
+
+namespace EssentialCSharp.Web.Services;
+
+public class RouteConfigurationService : IRouteConfigurationService
+{
+    private readonly IActionDescriptorCollectionProvider _ActionDescriptorCollectionProvider;
+    private readonly HashSet _StaticRoutes;
+
+    public RouteConfigurationService(IActionDescriptorCollectionProvider actionDescriptorCollectionProvider)
+    {
+        _ActionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
+        _StaticRoutes = ExtractStaticRoutes();
+    }
+
+    public IReadOnlySet GetStaticRoutes()
+    {
+        return _StaticRoutes;
+    }
+
+    private HashSet ExtractStaticRoutes()
+    {
+        var routes = new HashSet(StringComparer.OrdinalIgnoreCase);
+        
+        // Get all action descriptors
+        var actionDescriptors = _ActionDescriptorCollectionProvider.ActionDescriptors.Items;
+        
+        foreach (var actionDescriptor in actionDescriptors)
+        {
+            // Look for route attributes
+            if (actionDescriptor.AttributeRouteInfo?.Template != null)
+            {
+                string template = actionDescriptor.AttributeRouteInfo.Template;
+                
+                // Remove leading slash and add to our set
+                string routePath = template.TrimStart('/').ToLowerInvariant();
+                routes.Add(routePath);
+            }
+
+            // Skip the default fallback route (Index action in HomeController)
+            if (actionDescriptor.RouteValues.TryGetValue("action", out var action) && action == "Index")
+                continue;
+
+            // Skip Error actions
+            if (action == "Error")
+                continue;
+
+            // For actions without attribute routes, use conventional routing
+            if (actionDescriptor.AttributeRouteInfo?.Template == null &&
+                actionDescriptor.RouteValues.TryGetValue("action", out var actionName) && 
+                actionDescriptor.RouteValues.TryGetValue("controller", out var controllerName))
+            {
+                if (controllerName?.Equals("Home", StringComparison.OrdinalIgnoreCase) == true && actionName != null)
+                {
+                    // Use the action name directly as the route
+                    routes.Add(actionName.ToLowerInvariant());
+                }
+            }
+        }
+
+        return routes;
+    }
+}
diff --git a/EssentialCSharp.Web/appsettings.Development.json b/EssentialCSharp.Web/appsettings.Development.json
index 9f4ebdc8..f7e1d576 100644
--- a/EssentialCSharp.Web/appsettings.Development.json
+++ b/EssentialCSharp.Web/appsettings.Development.json
@@ -8,5 +8,8 @@
   },
   "ConnectionStrings": {
     "EssentialCSharpWebContextConnection": "Server=localhost;Database=EssentialCSharp.Web;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=true;"
+  },
+  "SiteSettings": {
+    "BaseUrl": "https://localhost:7184"
   }
 }
diff --git a/EssentialCSharp.Web/appsettings.json b/EssentialCSharp.Web/appsettings.json
index 711f6a36..f7622d36 100644
--- a/EssentialCSharp.Web/appsettings.json
+++ b/EssentialCSharp.Web/appsettings.json
@@ -9,5 +9,8 @@
   "HCaptcha": {
     "SecretKey": "0x0000000000000000000000000000000000000000",
     "SiteKey": "10000000-ffff-ffff-ffff-000000000001"
+  },
+  "SiteSettings": {
+    "BaseUrl": "https://essentialcsharp.com"
   }
 }
\ No newline at end of file