AstroBaaS

Search & discovery

XML Sitemap

Free — GPL coresize Splanned, not built

Generated from docs/plan/core/xml-sitemap/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.

XML Sitemap is a core feature that auto-generates a sitemap.xml file listing all products, pages, and blog posts. It ensures search engines index every page and increases organic visibility.

The problem

Search engines can’t discover all pages because merchants don’t have a sitemap; products are never indexed.

What it does

  • Generate sitemap.xml dynamically with all published products, pages, blogs, and categories
  • Support dynamic lastmod dates (product update time) and priority/changefreq fields
  • Auto-split large sitemaps (>50k URLs) into sitemap_1.xml, sitemap_2.xml with sitemap_index.xml
  • Cache sitemap and regenerate on schedule or product update
  • Admin dashboard: view sitemap stats (product count, last generation time)
  • Expose /sitemap.xml and /sitemap_index.xml as public routes

What it deliberately does NOT do

Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.

  • Does NOT submit sitemap to Google/Bing (reason: requires API keys, separate feature)
  • Does NOT track sitemap fetch errors (reason: requires Google Search Console API)
  • Does NOT include dynamic content like search results pages (reason: scope limited to products/pages/blogs)
  • Does NOT support image sitemaps (reason: separate feature)

Data model

New table: sitemap_cache (id, content_type, sitemap_part, xml_content, generated_at, expires_at). No new fields on products/pages/blogs (uses existing published_at, updated_at).

API

  • GET /sitemap.xml
  • GET /sitemap_index.xml
  • GET /api/sitemap/stats
  • POST /api/sitemap/regenerate

Every route added here must also appear in src/pages/openapi.json.ts — a test fails the build if it does not.

Admin

Dashboard: current sitemap size (product count), last generation time; stats showing products in sitemap vs total; regenerate button; view logs with generation times and errors.

The seam — why this is core

Core owns: sitemap generation, caching, public routes.

Core owns the interface + honest generator; sitemap is infrastructure, not a support commitment or credential.

Dependencies

  • Assumes product, page, blog_post tables exist with published_at, updated_at fields
  • Assumes cache/storage system exists
  • Assumes public route registration works

Acceptance checks

Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.

  • GET /sitemap.xml returns valid XML with >50 product URLs
  • Each product URL matches the actual product page URL
  • lastmod tag matches product’s updated_at timestamp
  • Unpublished or archived products are excluded
  • Sitemap index file generated if product count >50,000
  • Sitemap cache regenerated if product count changes by >1%
  • Response includes correct Content-Type (application/xml)
  • All storage drivers generate identical sitemaps
  • Sitemap generation time <10 seconds for 100k products (cached)
  • Merchant can manually trigger regenerate from admin UI

Risks

Cache staleness: if product update webhook fails, sitemap shows stale URL. Sitemap size expensive if merchant has 1M products. URL structure change: if merchant changes product URL format, old URLs in sitemap are dead links.

Commercial context

Suggested pricefree (core)
Rival anchorShopify: included; Magento: included

The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.


Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full catalogue and ../../AI-GUIDE.md for how to work on this repository.