Localize RSS feeds (rss_#2836
Conversation
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🏷️ Automatic Labeling SummaryThis PR has been automatically labeled based on the files changed and PR metadata. Applied Labels: testing,refactor,size-xl Label Categories
For more information, see |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
There was a problem hiding this comment.
Pull request overview
This PR localizes RSS generation across supported site languages and tightens sitemap URL emission so published URLs correspond to files that exist in the static site.
Changes:
- RSS scanning/rendering is now feed-language aware, with localized channel metadata and item links anchored to existing language variants.
- RSS generation now writes
rss.xmlplus localizedrss_<lang>.xmlfeeds where articles exist. - Sitemap generation now uses the canonical language list and existence checks for localized indexes, RSS feeds, and key static pages.
Reviewed changes
Copilot reviewed 6 out of 19 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
scripts/rss/scanner.ts |
Makes RSS article discovery language-aware and anchors items to requested variants. |
scripts/rss/render/feed.ts |
Localizes channel title, description, language, self-link, and item hreflang output. |
scripts/generate-rss.ts |
Loops over all supported languages and writes localized feed files. |
scripts/sitemap-xml/render/sitemap.ts |
Adds file-existence guards and language-driven localized URL enumeration. |
tests/generate-rss.test.ts |
Covers localized RSS channels and item anchoring. |
tests/generate-sitemap.test.ts |
Covers localized news indexes, RSS URLs, and backing-file invariants. |
rss_sv.xml |
Adds generated Swedish RSS feed output. |
| const file = feedPath(lang); | ||
| fs.writeFileSync(file, rss, 'utf8'); |
There was a problem hiding this comment.
Fixed in the latest commit. The postbuild script in package.json now copies all rss_*.xml files to dist/ after rss.xml:
"postbuild": "cp rss.xml dist/rss.xml && (cp rss_*.xml dist/ 2>/dev/null; exit 0) && cp sitemap.xml dist/sitemap.xml && ..."
The subshell with exit 0 ensures the step is always treated as optional — if no localized feed files exist yet, the build still succeeds.
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
|
@copilot analyse and improve code quality and test coverage and fix issues in failing checks |
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Fixed the failing Vitest job in commit f6f1aff. Root cause: two sitemap tests I added asserted Fix: guard those assertions with |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
|
@copilot analyse and improve code and test quality and fix all issues in TypeScript & JavaScript Testing / Unit Tests (Vitest) (pull_request) |
…aware Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Fixed the failing Vitest job in commit a608c3c. The actual failure was in a different pre-existing test file, Fix: made the 6 assertions existence-aware with Verification: |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
The chrome on every page references
rss_<lang>.xmlfeeds that were never generated (404s), andsitemap.xmlemitted many URLs without checking the backing file exists while hardcoding an 11-language news-index subset (missingja/ko/zh). This makes RSS per-language with localized titles/descriptions and guarantees the sitemap only advertises real URLs.RSS — localized per-language feeds
scripts/rss/scanner.ts:getRssArticles(feedLang)is now language-aware — anchors each item on the variant that exists infeedLang(so<link>/<guid>never point at a missing file) and reads the localized title/description from that variant's HTML. Defaults to'en'for byte-stable legacy output.scripts/rss/render/feed.ts:generateRss(lang)localizes the channel<title>,<description>(fromLANGUAGE_META.newsDesc),<language>(BCP-47, e.g.nbfor Norwegian), atom self-link, and per-item primary hreflang.scripts/generate-rss.ts: writesrss.xml(en) +rss_<lang>.xmlacross all 14 languages; skips non-English languages with zero translated articles so the build never advertises an empty/missing feed.sitemap.xml — URL validity & completeness
scripts/sitemap-xml/render/sitemap.ts: added anexistsAtRootguard on every emitted URL (index_*,politician-dashboard,political-intelligence_*,sitemap_*,news/index_*, and the RSS feeds).sitemap_*enumeration is now driven from the 14-entryLANGUAGESarray instead of hardcoded lists — fixes the missingja/ko/zhnews indexes.rss_<lang>.xmlURLs alongsiderss.xml.Deployment
package.jsonpostbuild: now copies everyrss_*.xmltodist/alongsiderss.xml, so the localized feeds advertised bydist/sitemap.xmlare actually present in the deployed output and don't reintroduce 404s. The copy is wrapped in a(cp rss_*.xml dist/ 2>/dev/null; exit 0)subshell so the build stays green when no localized feeds exist yet.Localized channel output, for reference:
Tests
tests/generate-rss.test.ts(localized sv/de/no channels, item anchoring on the feed language) andtests/generate-sitemap.test.ts(14-language news index, localized RSS URLs, and a "every emitted URL has a backing file" invariant).rss.xmlandsitemap_<lang>.htmlare guarded withfs.existsSyncso they only assert presence when the backing file exists — these artifacts are gitignored (/rss.xml,/sitemap*) and absent in the no-prebuild unit-test job, matching the sitemap's existence-check semantics.Notes for reviewers
rss.xmloutput is intentionally unchanged to preserve the existing contract.robots.txtis left as-is; localized feeds remain discoverable via per-page<link rel="alternate">and the sitemap.LANGUAGE_METAcovers every language with articles — worth confirming if a new language is added without translations.