From 1aa1216a9dc9e4d7d7a891d85e4ac5a611620d3f Mon Sep 17 00:00:00 2001 From: rzen Date: Sun, 12 Jul 2026 18:41:20 -0400 Subject: [PATCH] site: visible RSS pill on category and tag pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Autodiscovery alone is invisible since browsers dropped feed-detection UI — add a small RSS pill in the subheader (new feedHref prop on BaseLayout) linking to the page's scoped feed. Claude-Session: https://claude.ai/code/session_01WZaczDJjL3xZ3u5spsN5AL --- CHANGELOG.md | 2 +- README.md | 2 +- src/layouts/BaseLayout.astro | 25 +++++++++++++++++++++++++ src/pages/categories/[category].astro | 1 + src/pages/tags/[tag].astro | 1 + 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b300d9..5dd7766 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## July 2026 -- Feeds for everything: alongside the existing `/rss.xml`, add a JSON Feed 1.1 at `/feed.json`, per-category RSS at `/categories//rss.xml`, and per-tag RSS at `/tags//rss.xml` — all derived from a shared `src/lib/feed.ts` item source (reviews + posts + bundles, same visibility rules as the site). Category/tag pages advertise their scoped feed via `` autodiscovery; a new `/feeds/` directory page (linked from the footer) lists every feed with entry counts; every RSS feed carries an `atom:link` self reference and renders as a readable page in browsers via `public/feed.xsl` +- Feeds for everything: alongside the existing `/rss.xml`, add a JSON Feed 1.1 at `/feed.json`, per-category RSS at `/categories//rss.xml`, and per-tag RSS at `/tags//rss.xml` — all derived from a shared `src/lib/feed.ts` item source (reviews + posts + bundles, same visibility rules as the site). Category/tag pages advertise their scoped feed via `` autodiscovery and show a visible RSS pill in the subheader (browsers dropped feed-detection UI years ago, so autodiscovery alone is invisible); a new `/feeds/` directory page (linked from the footer) lists every feed with entry counts; every RSS feed carries an `atom:link` self reference and renders as a readable page in browsers via `public/feed.xsl` - Programmatic-reader pass: build-generated `/llms.txt` (llmstxt.org format — site description, feed/endpoint map, and every review, bundle, and post with one-line descriptions), `SearchAction` on the home-page `WebSite` JSON-LD wired to `/search/?q=`, and a "For robots" section on `/feeds/` documenting `search.json`, `llms.txt`, the sitemap, and JSON-LD coverage - Autonomous pipeline overhaul: new `/daily-pipeline` skill chains capture → bundle → review graduation → pick-of-the-day → build → commit → push and ends with a digest; `daily-finds` gains a score-and-shortlist stage (up to 12 `shortlist: true` finds per run, top 1-3 flagged as review candidates), feed-first fetching (`fetch: "feed"` + `feedUrl` in sources.json), cadence-aware scanning, and authority to apply mechanical source maintenance itself; `build-bundle`/`cluster-bundles`/`build-review` gain unattended `auto` modes (publish + log instead of pausing for confirmation), and `build-bundle weekly` writes a date-based "week's catch" so shortlisted finds never sit unbundled for weeks - Review heroes are now auto-discovered: `src/lib/hero.ts` globs `reviews/*/hero.` (images and `hero.mp4`), so a new review needs no registration — only legacy non-`hero`-named assets remain as explicit overrides; both hero globs also accept `.avif` diff --git a/README.md b/README.md index 913f90b..5848511 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Built with [Astro](https://astro.build) + MDX. - Auto-generated `/categories//` and `/tags//` listing pages — finds excluded by design - **Amazon affiliate handling** in `src/lib/affiliate.ts`: outbound links to Amazon (`amazon.com`, `amzn.to`, `a.co`, `smile.amazon.com`) get the configured tracking ID appended automatically; the link gets `rel="sponsored"`, an "Affiliate" badge appears next to it, and a one-line disclosure is shown beneath. Finds and reviews also take an optional `amazonLink` frontmatter field (canonical `/dp/` form) rendered as an "Also on Amazon" link — the capture pipeline populates it when a shortlisted physical product has an exact Amazon match. Add additional marketplace IDs (e.g. `amazon.co.uk`) to the `AMAZON_TAGS` map when needed - **SEO surface**: single `` component owning canonical, Open Graph, Twitter Card, feed autodiscovery, and JSON-LD; per-page structured data (`Review`, `BlogPosting`, `Product`, `Article`, `CollectionPage`, `ItemList`, `BreadcrumbList`, `WebSite` with `SearchAction`, `Organization`); auto-generated `sitemap-index.xml` (excludes `/grid/` and `/index3/`); `robots.txt`; static OG image fallbacks under `/public/og/`; promoted finds canonical to their review -- **Feeds everywhere**: site-wide RSS 2.0 at `/rss.xml` and JSON Feed 1.1 at `/feed.json`, plus per-category (`/categories//rss.xml`) and per-tag (`/tags//rss.xml`) RSS feeds, all derived from a single item source in `src/lib/feed.ts`; category/tag pages advertise their scoped feed via ``; a human-readable directory at `/feeds/` (footer-linked) lists every feed with counts; RSS renders as a readable page in browsers via `public/feed.xsl` +- **Feeds everywhere**: site-wide RSS 2.0 at `/rss.xml` and JSON Feed 1.1 at `/feed.json`, plus per-category (`/categories//rss.xml`) and per-tag (`/tags//rss.xml`) RSS feeds, all derived from a single item source in `src/lib/feed.ts`; category/tag pages advertise their scoped feed via `` and show a visible RSS pill in the subheader; a human-readable directory at `/feeds/` (footer-linked) lists every feed with counts; RSS renders as a readable page in browsers via `public/feed.xsl` - **Programmatic surface**: build-generated `/llms.txt` (llmstxt.org format — site map with every review/bundle/post and one-line descriptions, plus feed and endpoint pointers) and the full-site JSON index at `/search.json`, both documented in the "For robots" section of `/feeds/` - Custom 404 page with recent-reviews and navigation fallback - Light/dark mode via `prefers-color-scheme` diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 0429ae8..0c7f427 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -22,6 +22,8 @@ interface Props { jsonLd?: Record | Record[]; /** Page-scoped feeds (category/tag) advertised alongside the site-wide ones. */ feeds?: Array<{ title: string; href: string }>; + /** Visible RSS pill in the subheader pointing at this page's scoped feed. */ + feedHref?: string; /** Opt into the wider content tier on roomy viewports (grid/listing pages). */ wide?: boolean; } @@ -43,6 +45,7 @@ const { articleTags, jsonLd, feeds, + feedHref, wide, } = Astro.props; const siteName = 'Unique'; @@ -113,6 +116,11 @@ const year = new Date().getFullYear(); Updated

)} + {feedHref && ( +

+ RSS +

+ )} )} @@ -305,6 +313,23 @@ const year = new Date().getFullYear(); letter-spacing: 0.08em; color: var(--muted); } + .subheader-feed { margin: 0.45rem 0 0; } + .subheader-feed a { + display: inline-block; + padding: 0.05rem 0.5rem; + font-family: ui-sans-serif, system-ui, -apple-system, 'Helvetica Neue', sans-serif; + font-size: 0.66rem; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; + background: var(--rule); + color: var(--muted); + border-radius: 999px; + } + .subheader-feed a:hover { + color: var(--accent); + text-decoration: none; + } @media (max-width: 640px) { .masthead-row { diff --git a/src/pages/categories/[category].astro b/src/pages/categories/[category].astro index 3927d97..dcaf064 100644 --- a/src/pages/categories/[category].astro +++ b/src/pages/categories/[category].astro @@ -61,6 +61,7 @@ const breadcrumbs = buildBreadcrumbs([ ogImage={ogImage} jsonLd={[collectionPage, itemList, breadcrumbs]} feeds={[{ title: `Unique — ${category} (RSS)`, href: `/categories/${category}/rss.xml` }]} + feedHref={`/categories/${category}/rss.xml`} wide > diff --git a/src/pages/tags/[tag].astro b/src/pages/tags/[tag].astro index e7390b2..f86dce8 100644 --- a/src/pages/tags/[tag].astro +++ b/src/pages/tags/[tag].astro @@ -61,6 +61,7 @@ const breadcrumbs = buildBreadcrumbs([ ogImage={ogImage} jsonLd={[collectionPage, itemList, breadcrumbs]} feeds={[{ title: `Unique — #${tag} (RSS)`, href: `/tags/${tag}/rss.xml` }]} + feedHref={`/tags/${tag}/rss.xml`} wide >