title: RSS / Sitemap / Robots description: Dynamically generated SEO files: URL templates and runtime triggers.
RSS / Sitemap / Robots
All three SEO / feed files are generated at runtime. They are not static build outputs.
Sitemap
/sitemap.xml is generated by a top-level Pages Router handler (not under pages/[locale]/). Content sources:
i18n/config.tslocalesarray (one set of URLs per locale)data/site.tsurl(canonical base)data/projects(all web / game / early project IDs)data/life(all life slugs)- External
blog-index.json(when the external content repo is configured)
URL templates:
Each entry carries <lastmod>, <changefreq>, and <priority>. <priority> is in the 0.5–0.8 range; home is 0.8 and detail pages 0.6.
RSS
One feed per locale: /{locale}/rss.xml, generated by pages/[locale]/rss.xml.tsx.
<channel><title>/<description>/<language>(fromrssLanguageMap) /<link>/<lastBuildDate>come fromdata/site.tsplusi18n/config.ts<item>entries come from externalblog-index.json, sorted by published date descending- When the external repo is not configured, items are empty (only channel metadata)
Robots
/robots.txt is generated dynamically:
<base> is data/site.ts url (with a fallback of https://arsvine.com).
Hreflang
components/shared/HreflangLinks.tsx renders three <link rel="alternate" hreflang="..."> entries in the head of every locale page, so search engines know the three-language mapping. The hreflang values come from i18n/config.ts htmlLangMap (BCP-47).
Verification
After deploying:
Also use a browser or curl https://arsvine.com/sitemap.xml | head -50 to inspect URL completeness, especially whether newly added pages are included.
URL generation safety constraints
<base>comes fromdata/site.ts.siteConfig.urlorprocess.env.NEXT_PUBLIC_SITE_URL; it never accepts request-time injection- Path segments must pass their respective whitelists (locale + topic + id/slug regexes)
- Any untrusted string is routed through
lib/redirect-helpers.ts/lib/blog-client.tshelpers before being placed into a URL