Fixing an image sitemap XML parser failure in Spoonie
I fixed a Spoonie image sitemap that standard XML parsers could not read. An image URL with query parameters was written into image:loc without escaping its ampersands. PR #29 merged on November 11, 2026. I also fetched and parsed the production sitemap after the merge.
A valid image URL became invalid XML
An image URL such as ?auto=compress&fit=crop&w=1280 is fine as a URL. But within XML element text, & must be represented as &. In Spoonie’s particular sitemap serialization path with Next.js 16.4.2, that escaping was missing for image URL values. The image was not the problem. The XML output was.
<!-- Before -->
<image:loc>https://images.example/food.jpg?auto=compress&fit=crop</image:loc>
<!-- After -->
<image:loc>https://images.example/food.jpg?auto=compress&fit=crop</image:loc>
The change stayed at the output boundary
I updated the existing uniqueImages() helper in src/app/sitemap.ts to escape &, < and > before the image URLs reach the sitemap output. Recipes and Recipeed records already share that helper. I did not rewrite stored image URLs, change recipe data or replace the sitemap generator.
The regression test in the merged commit supplies an image query string, calls Next.js resolveSitemap(), and checks the resulting XML for &. This proves the demonstrated serialization problem is covered by a test, not that every possible crawler outcome has been verified.
Production readback
At 23:29 KST on November 11, 2026, the live sitemap returned HTTP 200 and passed Python’s xml.etree.ElementTree parser. At that moment the document contained 689 <url> entries, 872 <image:loc> entries and four & entity strings. Those counts are a snapshot, not a permanent catalogue size.
Google’s Search Console guidance identifies unescaped URL characters as a common sitemap parsing problem. Passing an XML parser establishes that the deployed document is well-formed. It does not establish indexing, improved search impressions or user growth.
The source PR, Next.js sitemap reference and my earlier Spoonie engineering note provide the code and product context.