fix(web): harden feed reader fallback and rss rendering#944
Merged
gildesmarais merged 4 commits intomainfrom Apr 4, 2026
Merged
fix(web): harden feed reader fallback and rss rendering#944gildesmarais merged 4 commits intomainfrom
gildesmarais merged 4 commits intomainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens the web feed rendering path and improves RSS/XSL presentation for better reader compatibility, adding shared UI assets and regression coverage around the responder and XSL output.
Changes:
- Adds/updates RSS XSL rendering (hero, “open in reader” affordance, and item quality indicators) and shared UI primitives.
- Refactors feed responder logging/normalization and tightens responder specs via shared expectations.
- Updates docs and ignore rules, including pnpm-related developer workflow notes.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| spec/public/rss_xsl_spec.rb | New regression coverage for XSL-rendered HTML output (assets, hero, stamping, text cleaning). |
| spec/html2rss/web/feeds/responder_spec.rb | Extracts shared expectations for static source resolution + cache headers. |
| spec/html2rss/web/app_spec.rb | Makes static-feed caching test less cache-collision prone via randomized path. |
| public/shared-ui.css | Expands shared primitives (hero/buttons/tokens) used by both app UI and XSL surfaces. |
| public/rss.xsl | Enhances feed HTML presentation, adds feed-reader link behavior, and improves text cleaning. |
| public/feed-reader-link.js | Adds client-side wiring for “Open in feed reader” fallback behavior. |
| Gemfile | Removes ssrf_filter dependency declaration. |
| docs/README.md | Updates contributor commands (notably make ready) and documents pnpm scripts. |
| docs/architecture.md | Refreshes routing/auth boundary documentation for static vs token feed paths. |
| app/web/feeds/responder.rb | Refactors request resolution + result emission flow for clearer separation. |
| .gitignore | Adds pnpm store and minor cleanup. |
This was referenced May 1, 2026
gildesmarais
added a commit
that referenced
this pull request
May 1, 2026
🤖 I have created a release *beep* *boop* --- ## [1.1.0](html2rss-web-v1.0.0...html2rss-web/v1.1.0) (2026-05-01) ### Features * add help text on error page ([eeee345](eeee345)), closes [#338](#338) * add routed frontend feed creation workflow ([#963](#963)) ([2d1b71a](2d1b71a)) * **auto_source:** add support for `auto_source` feature ([#676](#676)) ([531dced](531dced)) * default browserless onboarding and request strategies ([#895](#895)) ([377cff0](377cff0)) * **deps:** use html2rss in latest development status ([#728](#728)) ([5885d1d](5885d1d)) * **docker:** switch to alpine 21 ([7adcc89](7adcc89)) * **docker:** upgrade to use ruby 3.3 image ([ceafe24](ceafe24)) * **docker:** use multilayer build to cut image size in half ([2f6e322](2f6e322)) * **docker:** use Ruby 3.4 ([4f7d795](4f7d795)) * **frontend:** polish result experience and validation tooling ([#964](#964)) ([b11665e](b11665e)) * **frontend:** relaunch the app with a focused v1 flow ([e0692d7](e0692d7)) * **frontend:** unify feed/result state flow ([#943](#943)) ([6dfa1a9](6dfa1a9)) * **health_check:** add HTTP Basic authentication to `GET /health_check.txt` ([#559](#559)) ([d0ccd83](d0ccd83)) * improve example feed config in feed.yml and link to it ([#552](#552)) ([de08695](de08695)) * install Gemfile.lock specified bundler version ([4190160](4190160)) * integrate request_service and use ssrf_filter strategy by default ([#707](#707)) ([b7516fd](b7516fd)) * link included feeds to the instance feed directory ([#901](#901)) ([51ce79a](51ce79a)) * optionally allow APM using Sentry via env variable ([#696](#696)) ([94477d5](94477d5)) * redact sensitive feed data in structured logs ([#903](#903)) ([ee7df73](ee7df73)) * remove dependency on activesupport ([048cb73](048cb73)) * **runtime:** rebuild feed and api behavior around typed v1 services ([b61602d](b61602d)) * simplify feed creation contract & backend error handling ([#962](#962)) ([dfca027](dfca027)) * stabilize public http interface & slimmer docker ([#882](#882)) ([fe3f4be](fe3f4be)) * unify web and feed result surfaces ([#896](#896)) ([e747b23](e747b23)) * use parallel processing for feed retrieval in health_check.rb ([#665](#665)) ([4a24997](4a24997)) ### Bug Fixes * ArgumentError when RACK_TIMEOUT_SERVICE_TIMEOUT env var is set ([96acbab](96acbab)), closes [#527](#527) * **auto_source:** respect headers from global config ([#691](#691)) ([3e9ba91](3e9ba91)) * **build:** only cleanup when there is a test container ([f7bafa6](f7bafa6)) * caching with dynamic parameters yields incorrect rss ([#589](#589)) ([bb945c2](bb945c2)), closes [#587](#587) * **ci:** repair Ruby, OpenAPI, and frontend checks ([#880](#880)) ([ec6673b](ec6673b)) * defects for token/retry/loading UX ([#924](#924)) ([2d38633](2d38633)) * **docker:** missing curl installation for health check ([0bd9157](0bd9157)) * example feed in config/feeds.yml broken ([#664](#664)) ([b961897](b961897)) * **frontend:** preserve created feeds when preview loading fails ([#915](#915)) ([383ecc3](383ecc3)) * **frontend:** streamline web ux ([#916](#916)) ([85e79bf](85e79bf)) * harden container config defaults ([392997c](392997c)) * healthcheck broken due to missing curl ([c97e746](c97e746)) * keep unknown api v1 paths inside the api contract ([a820478](a820478)) * responds with http status 422 ([#738](#738)) ([ad9394c](ad9394c)) * **runtime:** polish relaunch smoke behavior and health checks ([65e1644](65e1644)) * stylesheets not included in feed ([#779](#779)) ([9116d9d](9116d9d)) * tzdata package not installed but required for tz conversion ([#663](#663)) ([55814d2](55814d2)) * **web:** harden feed reader fallback and rss rendering ([#944](#944)) ([438d9f6](438d9f6)) * **web:** harden observability env handling and Sentry log redaction ([#917](#917)) ([ed2b3e9](ed2b3e9)) ### Performance Improvements * enable YJIT ([729f31f](729f31f)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
gildesmarais
added a commit
that referenced
this pull request
May 1, 2026
🤖 I have created a release *beep* *boop* --- ## [1.2.0](v1.1.0...v1.2.0) (2026-05-01) ### Features * add help text on error page ([eeee345](eeee345)), closes [#338](#338) * add routed frontend feed creation workflow ([#963](#963)) ([2d1b71a](2d1b71a)) * **auto_source:** add support for `auto_source` feature ([#676](#676)) ([531dced](531dced)) * default browserless onboarding and request strategies ([#895](#895)) ([377cff0](377cff0)) * **deps:** use html2rss in latest development status ([#728](#728)) ([5885d1d](5885d1d)) * **docker:** switch to alpine 21 ([7adcc89](7adcc89)) * **docker:** upgrade to use ruby 3.3 image ([ceafe24](ceafe24)) * **docker:** use multilayer build to cut image size in half ([2f6e322](2f6e322)) * **docker:** use Ruby 3.4 ([4f7d795](4f7d795)) * **frontend:** polish result experience and validation tooling ([#964](#964)) ([b11665e](b11665e)) * **frontend:** relaunch the app with a focused v1 flow ([e0692d7](e0692d7)) * **frontend:** unify feed/result state flow ([#943](#943)) ([6dfa1a9](6dfa1a9)) * **health_check:** add HTTP Basic authentication to `GET /health_check.txt` ([#559](#559)) ([d0ccd83](d0ccd83)) * improve example feed config in feed.yml and link to it ([#552](#552)) ([de08695](de08695)) * install Gemfile.lock specified bundler version ([4190160](4190160)) * integrate request_service and use ssrf_filter strategy by default ([#707](#707)) ([b7516fd](b7516fd)) * link included feeds to the instance feed directory ([#901](#901)) ([51ce79a](51ce79a)) * optionally allow APM using Sentry via env variable ([#696](#696)) ([94477d5](94477d5)) * redact sensitive feed data in structured logs ([#903](#903)) ([ee7df73](ee7df73)) * remove dependency on activesupport ([048cb73](048cb73)) * **runtime:** rebuild feed and api behavior around typed v1 services ([b61602d](b61602d)) * simplify feed creation contract & backend error handling ([#962](#962)) ([dfca027](dfca027)) * stabilize public http interface & slimmer docker ([#882](#882)) ([fe3f4be](fe3f4be)) * unify web and feed result surfaces ([#896](#896)) ([e747b23](e747b23)) * use parallel processing for feed retrieval in health_check.rb ([#665](#665)) ([4a24997](4a24997)) ### Bug Fixes * ArgumentError when RACK_TIMEOUT_SERVICE_TIMEOUT env var is set ([96acbab](96acbab)), closes [#527](#527) * **auto_source:** respect headers from global config ([#691](#691)) ([3e9ba91](3e9ba91)) * **build:** only cleanup when there is a test container ([f7bafa6](f7bafa6)) * caching with dynamic parameters yields incorrect rss ([#589](#589)) ([bb945c2](bb945c2)), closes [#587](#587) * **ci:** repair Ruby, OpenAPI, and frontend checks ([#880](#880)) ([ec6673b](ec6673b)) * **ci:** robustly parse release tags and align config ([#972](#972)) ([2efd6ef](2efd6ef)) * defects for token/retry/loading UX ([#924](#924)) ([2d38633](2d38633)) * **docker:** missing curl installation for health check ([0bd9157](0bd9157)) * example feed in config/feeds.yml broken ([#664](#664)) ([b961897](b961897)) * **frontend:** preserve created feeds when preview loading fails ([#915](#915)) ([383ecc3](383ecc3)) * **frontend:** streamline web ux ([#916](#916)) ([85e79bf](85e79bf)) * harden container config defaults ([392997c](392997c)) * healthcheck broken due to missing curl ([c97e746](c97e746)) * keep unknown api v1 paths inside the api contract ([a820478](a820478)) * responds with http status 422 ([#738](#738)) ([ad9394c](ad9394c)) * **runtime:** polish relaunch smoke behavior and health checks ([65e1644](65e1644)) * stylesheets not included in feed ([#779](#779)) ([9116d9d](9116d9d)) * tzdata package not installed but required for tz conversion ([#663](#663)) ([55814d2](55814d2)) * **web:** harden feed reader fallback and rss rendering ([#944](#944)) ([438d9f6](438d9f6)) * **web:** harden observability env handling and Sentry log redaction ([#917](#917)) ([ed2b3e9](ed2b3e9)) ### Performance Improvements * enable YJIT ([729f31f](729f31f)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This pull request introduces several improvements to the feed rendering experience, both visually and functionally, along with some internal refactoring and documentation updates. The most significant changes are a major redesign of the RSS feed XSL template to enhance the UI, the addition of a script to improve feed reader link handling, and a refactor in the feed responder logic. There are also updates to documentation for clarity and accuracy.
Feed UI and UX improvements:
public/rss.xsltemplate to provide a more modern, accessible, and informative feed presentation. This includes a new hero section with icons, improved layout, additional metadata (such as updated/published stamps), and visual signals for item quality (summary, image, tags, byline). The CSS has been extensively updated to support these changes. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]Feed reader integration:
public/feed-reader-link.js, which dynamically sets the "Open in feed reader" link to use thefeed:protocol for the current page if not already set, improving compatibility with feed readers. The script is now included in the XSL template. [1] [2] [3]Backend code refactoring:
app/web/feeds/responder.rbby extracting request resolution into a newresolve_requestmethod and improving result emission withemit_response_result, making the code more modular and readable. [1] [2]Documentation and developer experience:
docs/README.mdto clarify make targets, add new OpenAPI verification/linting commands, and switch frontend instructions from npm to pnpm for consistency.docs/architecture.mdto clarify feed routing, authentication, and source resolution logic, with more precise descriptions of static and token-backed feeds.Dependency cleanup:
ssrf_filtergem from theGemfile.