site: visible RSS pill on category and tag pages
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
This commit is contained in:
+1
-1
@@ -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/<name>/rss.xml`, and per-tag RSS at `/tags/<name>/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 `<link rel="alternate">` 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/<name>/rss.xml`, and per-tag RSS at `/tags/<name>/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 `<link rel="alternate">` 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.<ext>` (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`
|
||||
|
||||
@@ -20,7 +20,7 @@ Built with [Astro](https://astro.build) + MDX.
|
||||
- Auto-generated `/categories/<name>/` and `/tags/<name>/` 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/<ASIN>` 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 `<SEO>` 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/<name>/rss.xml`) and per-tag (`/tags/<name>/rss.xml`) RSS feeds, all derived from a single item source in `src/lib/feed.ts`; category/tag pages advertise their scoped feed via `<link rel="alternate">`; 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/<name>/rss.xml`) and per-tag (`/tags/<name>/rss.xml`) RSS feeds, all derived from a single item source in `src/lib/feed.ts`; category/tag pages advertise their scoped feed via `<link rel="alternate">` 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`
|
||||
|
||||
@@ -22,6 +22,8 @@ interface Props {
|
||||
jsonLd?: Record<string, unknown> | Record<string, unknown>[];
|
||||
/** 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 <time datetime={updatedDate.toISOString()}>{fmtLong.format(updatedDate)}</time>
|
||||
</p>
|
||||
)}
|
||||
{feedHref && (
|
||||
<p class="subheader-feed">
|
||||
<a href={feedHref}>RSS</a>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
>
|
||||
<EntryGrid entries={entries} />
|
||||
|
||||
@@ -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
|
||||
>
|
||||
<EntryGrid entries={entries} />
|
||||
|
||||
Reference in New Issue
Block a user