feat(blog): add RSS feed at /blog/rss.xml#149
Conversation
Generates an RSS 2.0 feed from the blog .svx frontmatter, exposes it via <link rel="alternate"> for autodiscovery, and adds a visible RSS button on the blog index so readers can subscribe.
|
/dobby review this PR |
|
Dobby is on it! Dobby will review this pull request very carefully and report back with findings, sir! |
There was a problem hiding this comment.
Review summary
Looks good overall — clean implementation that mirrors sitemap.xml/+server.js, builds cleanly, and produces valid RSS. Approving with a few small, non-blocking suggestions.
Verified locally
npm ci --legacy-peer-deps && npm run buildsucceeds;build/blog/rss.xmlis emitted with both posts in newest-first order.npx svelte-check --threshold warning→ 0 errors / 0 warnings.npx prettier --checkandnpx eslintclean on the changed files.- Generated XML is well-formed; frontmatter is correctly XML-escaped (e.g.
'→'in the "Looking ahead" description).
Strengths
- Uses
prerender = trueplusimport.meta.glob(..., { eager: true }), so the feed is a static file at deploy time — no runtime cost and no SSR surprises withadapter-static. escapeXmlcovers all five XML predefined entities and toleratesnull/undefinedviaString(value ?? '').toRfc822falls back to "now" on invalid dates instead of emittingInvalid Date.- Autodiscovery
<link rel="alternate" type="application/rss+xml">on the blog index is exactly what feed readers look for. - PR title is conventional-commit (
feat(blog): …), sopr-title.ymlwill pass.
Suggestions (non-blocking)
-
Trailing-slash mismatch with canonical URLs. The marketing layout sets
trailingSlash = 'always'(from PR #104), so the actual canonical URLs arehttps://postguard.eu/blog/<slug>/. The feed emitshttps://postguard.eu/blog/<slug>(no trailing slash) for both<link>and<guid isPermaLink="true">. Aggregators that dedupe by GUID or canonical URL may treat these as different from the on-page canonical / sitemap entries. Suggest:const url = `${SITE_URL}/blog/${post.slug}/`
to match
sitemap.xml/+server.js(https://postguard.eu${e.path}/) andSEO.svelte's derived canonical. -
Hardcoded
<language>en</language>. The site shipsenandnltranslations. The current.svxfiles insrc/content/blog/are English-only, soenis correct today, but worth a// TODOif multi-language posts are on the roadmap (one feed per locale is the usual pattern). -
descriptioncould use CDATA if HTML ever sneaks into frontmatter. Today the descriptions are plain text and escaping is sufficient; if you later allow inline markup indescription, switch to:<description><![CDATA[...]]></description>
Not needed now.
-
<dc:creator>is good, but RSS 2.0's native<author>field expects an email address, which you're (correctly) not exposing. Thedc:creatorchoice is the right one — no change requested, just calling it out for future readers. -
Optional polish: add the same autodiscovery
<link>to individual blog post pages (/blog/[slug]) so a reader visiting a single post can also subscribe. Not required.
Test plan items still pending
- Validating at https://validator.w3.org/feed/ post-deploy — the local output looks compliant, but a real validator run is the right backstop.
- Reader autodiscovery from
/blog.
Ship it after addressing (1) if you agree the canonical URL should match the rest of the site; everything else is taste.
…r from posts Marketing routes use trailingSlash = 'always', so the feed's <link> and <guid isPermaLink="true"> values now end in '/' to match the on-page canonical and sitemap entries — preventing aggregators from treating the feed and the canonical as separate items. Also adds the RSS autodiscovery <link> to individual blog posts so readers visiting a single article can subscribe.
|
/dobby please re-review — addressed the trailing-slash mismatch (channel link, item links, and GUIDs now end in |
|
/dobby add the manual testing to encryption4all/postguard-business#48 |
|
Dobby is on it! Dobby will check the trailing-slash fixes and the RSS autodiscovery additions, and report back with a fresh review. Dobby thanks you for addressing the feedback so quickly! |
|
This agent is on it! Eager to copy the manual testing notes over to postguard-business issue 48 right away! |
There was a problem hiding this comment.
Re-review summary
Fixes look great — approving. Both follow-ups from the prior review are in place and verified locally.
Verified locally
npm ci --legacy-peer-deps && npm run buildsucceeds;build/blog/rss.xmlis emitted.- Channel
<link>, item<link>, and<guid isPermaLink="true">all end in/now, matchingtrailingSlash = 'always'and the sitemap entries — aggregators will no longer see the feed and the canonical as separate items. - RSS autodiscovery
<link rel="alternate" type="application/rss+xml" href="/blog/rss.xml">is now present in the built HTML for/blog/,/blog/looking-ahead-with-postguard/, and/blog/introducing-postguard/. npx svelte-check --threshold warning→ 0 errors / 0 warnings / 0 files with problems.npx prettier --checkandnpx eslintclean on the changed files.- Generated XML parses cleanly (well-formed).
Spot-check of generated feed
<channel>
<link>https://postguard.eu/blog/</link>
...
<item>
<link>https://postguard.eu/blog/looking-ahead-with-postguard/</link>
<guid isPermaLink="true">https://postguard.eu/blog/looking-ahead-with-postguard/</guid>Skipped items (acknowledged)
- Hardcoded
<language>en</language>TODO — fine, posts are English-only today. - CDATA wrap for
description— not needed while frontmatter stays plain text. <author>vs<dc:creator>—dc:creatorremains the right call (no email exposure).
Still pending (deploy-time, not blockers)
- Validate at https://validator.w3.org/feed/ post-deploy.
- Confirm a real RSS reader can autodiscover and subscribe from
/blog/.
LGTM — ship it.
|
Added the manual testing for this PR to the staging checklist as §8 "postguard.eu — blog RSS feed": encryption4all/postguard-business#48 (comment) |
Summary
/blog/rss.xml, generated from each post's.svxfrontmatter (title, description, date, author).<link rel="alternate" type="application/rss+xml">on the blog index for reader autodiscovery.Implementation notes
src/routes/sitemap.xml/+server.js(vanilla JS + JSDoc,prerender = true,import.meta.globover/src/content/blog/*.svx).lastBuildDatetracks the most recent post.Test plan
npm run buildsucceeds and emitsbuild/blog/rss.xml.npx svelte-checkpasses (0 errors / 0 warnings).npx eslintandnpx prettier --checkpass on the changed files./blog.