feat: implement SEO enhancements and sitemap generation
Build and Deploy to Kubernetes / build-and-deploy (push) Has been cancelled
Build and Deploy to Kubernetes / build-and-deploy (push) Has been cancelled
- Added SEO configuration settings in appsettings for both development and staging environments, including site URL, name, and default description. - Registered SEO-related services in the dependency injection container, including `SeoMetadataProvider` and `SitemapGenerator`. - Updated the main program to configure SEO settings and map a new endpoint for generating the sitemap. - Enhanced the `_Host.cshtml` page to utilize SEO metadata, including title, description, and Open Graph tags, improving search engine visibility and user engagement. These changes significantly enhance the SEO capabilities of the application, ensuring better indexing and presentation in search results.
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace FrontOffice.Main.Utilities.Seo;
|
||||
|
||||
public class SitemapGenerator
|
||||
{
|
||||
private readonly BlogPostService _blogPostService;
|
||||
private readonly SeoSettings _settings;
|
||||
|
||||
private static readonly string[] StaticPaths =
|
||||
[
|
||||
RouteConstants.Main.MainPage,
|
||||
RouteConstants.About.Index,
|
||||
RouteConstants.FAQ.Index,
|
||||
RouteConstants.Contact.Index,
|
||||
RouteConstants.Licenses.Index,
|
||||
RouteConstants.Blog.Index,
|
||||
RouteConstants.Store.Products,
|
||||
RouteConstants.Package.List,
|
||||
RouteConstants.Club.Membership,
|
||||
RouteConstants.Club.Features,
|
||||
RouteConstants.DiscountStore.Products,
|
||||
RouteConstants.Registration.Wizard,
|
||||
];
|
||||
|
||||
public SitemapGenerator(BlogPostService blogPostService, IOptions<SeoSettings> settings)
|
||||
{
|
||||
_blogPostService = blogPostService;
|
||||
_settings = settings.Value;
|
||||
}
|
||||
|
||||
public async Task<string> GenerateAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var baseUrl = _settings.SiteUrl.TrimEnd('/');
|
||||
var ns = XNamespace.Get("http://www.sitemaps.org/schemas/sitemap/0.9");
|
||||
var urls = new List<XElement>();
|
||||
|
||||
foreach (var path in StaticPaths)
|
||||
{
|
||||
urls.Add(CreateUrlElement(ns, $"{baseUrl}{path}", priority: path == "/" ? "1.0" : "0.8"));
|
||||
}
|
||||
|
||||
var page = 1;
|
||||
const int pageSize = 100;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var result = await _blogPostService.GetPublishedPostsAsync(page: page, pageSize: pageSize);
|
||||
if (result.Posts.Count == 0)
|
||||
break;
|
||||
|
||||
foreach (var post in result.Posts)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(post.Slug))
|
||||
continue;
|
||||
|
||||
var lastMod = post.PublishedAt?.ToString("yyyy-MM-dd") ?? DateTime.UtcNow.ToString("yyyy-MM-dd");
|
||||
urls.Add(CreateUrlElement(
|
||||
ns,
|
||||
$"{baseUrl}{RouteConstants.Blog.Post}{post.Slug}",
|
||||
lastMod: lastMod,
|
||||
priority: "0.6"));
|
||||
}
|
||||
|
||||
if (page >= result.TotalPages)
|
||||
break;
|
||||
|
||||
page++;
|
||||
}
|
||||
|
||||
var document = new XDocument(
|
||||
new XDeclaration("1.0", "UTF-8", null),
|
||||
new XElement(ns + "urlset", urls));
|
||||
|
||||
var builder = new StringBuilder();
|
||||
using (var writer = new StringWriter(builder))
|
||||
{
|
||||
document.Save(writer);
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private static XElement CreateUrlElement(
|
||||
XNamespace ns,
|
||||
string loc,
|
||||
string? lastMod = null,
|
||||
string changefreq = "weekly",
|
||||
string priority = "0.5")
|
||||
{
|
||||
var element = new XElement(ns + "url",
|
||||
new XElement(ns + "loc", loc),
|
||||
new XElement(ns + "changefreq", changefreq),
|
||||
new XElement(ns + "priority", priority));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(lastMod))
|
||||
element.Add(new XElement(ns + "lastmod", lastMod));
|
||||
|
||||
return element;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user