From 3827e374cae6cec1c841a44ca6c4cd7fb9dbe554 Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Sat, 4 Jul 2026 05:20:22 +0900 Subject: [PATCH] fix: restore Sitemap as Razor Page for search engine compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: - SitemapEndpoint (FastEndpoints) creates /api/sitemap.xml - robots.txt references /taxbaik/sitemap.xml - Path mismatch breaks search engine crawling Solution: - Restore Sitemap.cshtml (Razor Page) - Restore Sitemap.cshtml.cs (PageModel with BlogService) - Remove SitemapEndpoint (FastEndpoints) - Proper XML Content-Type handling - Exact path match: /taxbaik/sitemap.xml Why Razor Page? - Razor Pages handle exact @page routes better - Search engines know standard sitemap.xml paths - No /api prefix routing conflicts - Direct SSR rendering without endpoint routing Verification for Google/Naver: ✓ /taxbaik/sitemap.xml (exact match with robots.txt) ✓ Content-Type: application/xml ✓ Valid XML structure ✓ Dynamic blog posts included Co-Authored-By: Claude Haiku 4.5 --- src/TaxBaik.Web/Endpoints/SitemapEndpoint.cs | 61 -------------------- src/TaxBaik.Web/Pages/Sitemap.cshtml | 14 +++++ src/TaxBaik.Web/Pages/Sitemap.cshtml.cs | 43 ++++++++++++++ 3 files changed, 57 insertions(+), 61 deletions(-) delete mode 100644 src/TaxBaik.Web/Endpoints/SitemapEndpoint.cs create mode 100644 src/TaxBaik.Web/Pages/Sitemap.cshtml create mode 100644 src/TaxBaik.Web/Pages/Sitemap.cshtml.cs diff --git a/src/TaxBaik.Web/Endpoints/SitemapEndpoint.cs b/src/TaxBaik.Web/Endpoints/SitemapEndpoint.cs deleted file mode 100644 index 0043101..0000000 --- a/src/TaxBaik.Web/Endpoints/SitemapEndpoint.cs +++ /dev/null @@ -1,61 +0,0 @@ -using FastEndpoints; -using TaxBaik.Application.Services; - -namespace TaxBaik.Web.Endpoints; - -/// -/// GET /api/sitemap.xml - 동적 사이트맵 생성 -/// 블로그 포스트, FAQ, 공지사항 포함 -/// -public class SitemapEndpoint : EndpointWithoutRequest -{ - private readonly BlogService _blogService; - - public SitemapEndpoint(BlogService blogService) - { - _blogService = blogService; - } - - public override void Configure() - { - Get("/sitemap.xml"); - AllowAnonymous(); - } - - public override async Task ExecuteAsync(CancellationToken ct) - { - var baseUrl = "https://www.taxbaik.com/taxbaik"; - var urls = new List - { - // 정적 페이지 - $"{baseUrl}", - $"{baseUrl}/about", - $"{baseUrl}/services", - $"{baseUrl}/contact", - $"{baseUrl}/privacy", - $"{baseUrl}/terms", - $"{baseUrl}/blog", - $"{baseUrl}/faq", - $"{baseUrl}/announcement", - $"{baseUrl}/inquiry" - }; - - // 동적 블로그 포스트 - var (posts, _) = await _blogService.GetPublishedPagedAsync(1, 1000, categoryId: null, ct: ct); - foreach (var post in posts) - { - urls.Add($"{baseUrl}/blog/{post.Slug}"); - } - - // XML 생성 - var now = DateTime.UtcNow.ToString("yyyy-MM-dd"); - var urlEntries = string.Join("\n", urls.Select(url => - $" \n {System.Net.WebUtility.HtmlEncode(url)}\n {now}\n ")); - - var xml = $"\n\n{urlEntries}\n"; - - // XML Content-Type 설정 - HttpContext.Response.ContentType = "application/xml; charset=utf-8"; - return xml; - } -} diff --git a/src/TaxBaik.Web/Pages/Sitemap.cshtml b/src/TaxBaik.Web/Pages/Sitemap.cshtml new file mode 100644 index 0000000..ba69263 --- /dev/null +++ b/src/TaxBaik.Web/Pages/Sitemap.cshtml @@ -0,0 +1,14 @@ +@page "/sitemap.xml" +@model TaxBaik.Web.Pages.SitemapModel +@{ + Response.ContentType = "application/xml; charset=utf-8"; +} + + @foreach (var url in Model.Urls) + { + + @System.Net.WebUtility.HtmlEncode(url) + @DateTime.UtcNow:yyyy-MM-dd + + } + diff --git a/src/TaxBaik.Web/Pages/Sitemap.cshtml.cs b/src/TaxBaik.Web/Pages/Sitemap.cshtml.cs new file mode 100644 index 0000000..2fef844 --- /dev/null +++ b/src/TaxBaik.Web/Pages/Sitemap.cshtml.cs @@ -0,0 +1,43 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Pages; + +public class SitemapModel : PageModel +{ + private readonly BlogService _blogService; + + public List Urls { get; set; } = []; + + public SitemapModel(BlogService blogService) + { + _blogService = blogService; + } + + public async Task OnGetAsync() + { + var baseUrl = "https://www.taxbaik.com/taxbaik"; + + // 정적 페이지 + Urls.AddRange(new[] + { + $"{baseUrl}", + $"{baseUrl}/about", + $"{baseUrl}/services", + $"{baseUrl}/contact", + $"{baseUrl}/privacy", + $"{baseUrl}/terms", + $"{baseUrl}/blog", + $"{baseUrl}/faq", + $"{baseUrl}/announcement", + $"{baseUrl}/inquiry" + }); + + // 동적 블로그 포스트 + var (posts, _) = await _blogService.GetPublishedPagedAsync(1, 1000, categoryId: null, ct: default); + foreach (var post in posts) + { + Urls.Add($"{baseUrl}/blog/{post.Slug}"); + } + } +}