Skip to content

Localize RSS feeds (rss_#2836

Merged
pethers merged 7 commits into
mainfrom
copilot/improve-sitemap-rss-generation
May 30, 2026
Merged

Localize RSS feeds (rss_#2836
pethers merged 7 commits into
mainfrom
copilot/improve-sitemap-rss-generation

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 30, 2026

The chrome on every page references rss_<lang>.xml feeds that were never generated (404s), and sitemap.xml emitted many URLs without checking the backing file exists while hardcoding an 11-language news-index subset (missing ja/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 in feedLang (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> (from LANGUAGE_META.newsDesc), <language> (BCP-47, e.g. nb for Norwegian), atom self-link, and per-item primary hreflang.
  • scripts/generate-rss.ts: writes rss.xml (en) + rss_<lang>.xml across 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 an existsAtRoot guard on every emitted URL (index_*, politician-dashboard, political-intelligence_*, sitemap_*, news/index_*, and the RSS feeds).
  • News-index and sitemap_* enumeration is now driven from the 14-entry LANGUAGES array instead of hardcoded lists — fixes the missing ja/ko/zh news indexes.
  • Added existence-checked localized rss_<lang>.xml URLs alongside rss.xml.

Deployment

  • package.json postbuild: now copies every rss_*.xml to dist/ alongside rss.xml, so the localized feeds advertised by dist/sitemap.xml are 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:

<!-- rss_sv.xml -->
<title>Riksdagsmonitor — Nyheter &amp; Analys (Svenska)</title>
<language>sv</language>
<description>Senaste politiska nyheter, analyser och uppdateringar från Sveriges riksdag och regering.</description>
<atom:link href="https://riksdagsmonitor.com/rss_sv.xml" rel="self" type="application/rss+xml"/>

Tests

  • Extended tests/generate-rss.test.ts (localized sv/de/no channels, item anchoring on the feed language) and tests/generate-sitemap.test.ts (14-language news index, localized RSS URLs, and a "every emitted URL has a backing file" invariant).
  • Sitemap assertions on rss.xml and sitemap_<lang>.html are guarded with fs.existsSync so 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

  • English rss.xml output is intentionally unchanged to preserve the existing contract.
  • robots.txt is left as-is; localized feeds remain discoverable via per-page <link rel="alternate"> and the sitemap.
  • The skip-empty-feed behavior assumes LANGUAGE_META covers every language with articles — worth confirming if a new language is added without translations.

Copilot AI and others added 2 commits May 30, 2026 06:31
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@pethers pethers marked this pull request as ready for review May 30, 2026 06:40
Copilot AI review requested due to automatic review settings May 30, 2026 06:40
@github-actions github-actions Bot added testing Test coverage refactor Code refactoring size-xl Extra large change (> 1000 lines) labels May 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🏷️ Automatic Labeling Summary

This PR has been automatically labeled based on the files changed and PR metadata.

Applied Labels: testing,refactor,size-xl

Label Categories

  • 🗳️ Content: news, dashboard, visualization, intelligence
  • 💻 Technology: html-css, javascript, workflow, security
  • 📊 Data: cia-data, riksdag-data, data-pipeline, schema
  • 🌍 I18n: i18n, translation, rtl
  • 🔒 ISMS: isms, iso-27001, nist-csf, cis-controls
  • 🏗️ Infrastructure: ci-cd, deployment, performance, monitoring
  • 🔄 Quality: testing, accessibility, documentation, refactor
  • 🤖 AI: agent, skill, agentic-workflow

For more information, see .github/labeler.yml.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.xml plus localized rss_<lang>.xml feeds 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.

Comment thread scripts/generate-rss.ts
Comment on lines +65 to +66
const file = feedPath(lang);
fs.writeFileSync(file, rss, 'utf8');
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Copilot AI requested a review from pethers May 30, 2026 07:00
@github-actions github-actions Bot added the dependencies Dependency updates label May 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers
Copy link
Copy Markdown
Member

pethers commented May 30, 2026

@copilot analyse and improve code quality and test coverage and fix issues in

failing checks
TypeScript & JavaScript Testing / Unit Tests (Vitest) (pull_request)
TypeScript & JavaScript Testing / Unit Tests (Vitest) (pull_request)Failing after 5m

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 30, 2026

@copilot analyse and improve code quality and test coverage and fix issues in

failing checks
...

Fixed the failing Vitest job in commit f6f1aff.

Root cause: two sitemap tests I added asserted rss.xml and sitemap_sv.html unconditionally, but both are gitignored (/rss.xml, /sitemap*) and only produced during prebuild. The unit-test job runs without prebuild, so those files are absent and the existence-checked sitemap correctly omits them — making the assertions fail.

Fix: guard those assertions with fs.existsSync so they only assert presence when the backing file exists (matching the sitemap's existence-check semantics and the sibling tests at lines 109/129). The committed rss_<lang>.xml feeds still provide real assertion coverage. Both tests/generate-sitemap.test.ts and tests/generate-rss.test.ts now pass (74/74), and npm run build:lib typechecks clean.

Copilot AI changed the title Localize RSS feeds (rss_<lang>.xml) and validate every sitemap.xml URL Localize RSS feeds (rss_ May 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers
Copy link
Copy Markdown
Member

pethers commented May 30, 2026

@copilot analyse and improve code and test quality and fix all issues in TypeScript & JavaScript Testing / Unit Tests (Vitest) (pull_request)
TypeScript & JavaScript Testing / Unit Tests (Vitest) (pull_request)Failing after 5m

…aware

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 30, 2026

@copilot analyse and improve code and test quality and fix all issues in [TypeScript & JavaScript Testing / Unit Tests (Vitest) (pull_request)](https://github.com/Hack23/riksdagsmonito...

Fixed the failing Vitest job in commit a608c3c.

The actual failure was in a different pre-existing test file, tests/sitemap-generation.test.ts (6 failing tests), not the generate-sitemap.test.ts I touched earlier. Those tests asserted unconditional emission of news/, news/index_<lang>.html, sitemap.html, and sitemap_<lang>.html URLs. Those HTML files are build-generated and gitignored, so they're absent in the no-prebuild unit-test job. On main the tests passed only because the old sitemap emitted those URLs unconditionally — but this PR's whole point is to existence-check every emitted URL, so the sitemap now correctly omits them, breaking the stale assertions.

Fix: made the 6 assertions existence-aware with fs.existsSync, matching the convention already used by the sibling dashboard test (line ~302) and the sitemap's runtime semantics. The assertions still fire fully when the backing files exist (verified by generating the HTML sitemaps and confirming the production-shape assertion passes), and become no-ops only when prebuild hasn't run.

Verification: tests/sitemap-generation.test.ts 38/38, plus generate-sitemap.test.ts + generate-rss.test.ts → 112/112 combined; npm run build:lib typechecks clean.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers pethers merged commit 21f4fd1 into main May 30, 2026
18 of 19 checks passed
@pethers pethers deleted the copilot/improve-sitemap-rss-generation branch May 30, 2026 08:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Dependency updates refactor Code refactoring size-xl Extra large change (> 1000 lines) testing Test coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants