From 5cc20ea562d4d814e8ba73c814db36f417ad8dd4 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Mon, 31 Aug 2026 08:38:21 -0400 Subject: [PATCH 1/2] Generalize Breadcrumbs and add an override hook The whiskey.fm fork carried a Breadcrumbs customization that had no override hook after the integration conversion: an intermediate Collections crumb on /collections/* pages, aria-current="page" on the last crumb, and a BreadcrumbList schema built from the full trail. Instead of porting the fork's hardcoded /collections/* handling, the component now derives the trail from the URL segments, so any nested page a consuming site adds gets titleized intermediate crumbs (and matching schema) automatically; the final crumb still uses the page title. Breadcrumbs is also in OVERRIDABLE_COMPONENTS for sites that want different behavior entirely. Co-Authored-By: Claude Fable 5 --- packages/starpod/README.md | 4 +- .../starpod/src/components/Breadcrumbs.astro | 104 +++++++++++------- packages/starpod/src/index.ts | 1 + packages/starpod/src/layouts/Layout.astro | 2 +- 4 files changed, 66 insertions(+), 45 deletions(-) diff --git a/packages/starpod/README.md b/packages/starpod/README.md index 1dc8426e..9c14b2e8 100644 --- a/packages/starpod/README.md +++ b/packages/starpod/README.md @@ -105,8 +105,8 @@ starpod(starpodConfig, { }); ``` -Overridable components: `Dots`, `EpisodeList`, `Hosts`, `InfoCard`, -`LargePlatforms`, `NotFoundContent`, `Platforms`, `ShowArtwork`. +Overridable components: `Breadcrumbs`, `Dots`, `EpisodeList`, `Hosts`, +`InfoCard`, `LargePlatforms`, `NotFoundContent`, `Platforms`, `ShowArtwork`. ## Custom pages diff --git a/packages/starpod/src/components/Breadcrumbs.astro b/packages/starpod/src/components/Breadcrumbs.astro index 5424bba2..9cccf12d 100644 --- a/packages/starpod/src/components/Breadcrumbs.astro +++ b/packages/starpod/src/components/Breadcrumbs.astro @@ -1,31 +1,42 @@ --- import { Schema } from 'astro-seo-schema'; -const { url } = Astro; - export interface Props { title: string; } const { title } = Astro.props; +const { pathname } = Astro.url; + +/** "my-cool-page" -> "My Cool Page" */ +function titleize(segment: string): string { + return decodeURIComponent(segment) + .split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); +} + +// Every path segment becomes a crumb, so nested routes (e.g. a site's +// /collections/some-collection page) get intermediate crumbs linking to +// their cumulative path. The final crumb uses the page's own title. +const segments = pathname.split('/').filter(Boolean); +const crumbs = [ + { name: 'Home', href: '/' }, + ...segments.map((segment, index) => ({ + name: index === segments.length - 1 ? title : titleize(segment), + href: '/' + segments.slice(0, index + 1).join('/') + })) +]; const breadcrumbSchema = { '@context': 'https://schema.org', '@type': 'BreadcrumbList', - itemListElement: [ - { - '@type': 'ListItem', - position: 1, - name: 'Home', - item: Astro.site?.toString() || '/' - }, - { - '@type': 'ListItem', - position: 2, - name: title, - item: new URL(url, Astro.site).toString() - } - ] + itemListElement: crumbs.map((crumb, index) => ({ + '@type': 'ListItem', + position: index + 1, + name: crumb.name, + item: new URL(crumb.href, Astro.site).toString() + })) }; --- @@ -33,31 +44,40 @@ const breadcrumbSchema = { diff --git a/packages/starpod/src/index.ts b/packages/starpod/src/index.ts index 8f4f7772..047bad14 100644 --- a/packages/starpod/src/index.ts +++ b/packages/starpod/src/index.ts @@ -22,6 +22,7 @@ import { * module everywhere at once. */ const OVERRIDABLE_COMPONENTS = { + Breadcrumbs: './components/Breadcrumbs.astro', Dots: './components/Dots.astro', EpisodeList: './components/EpisodeList.astro', Hosts: './components/Hosts.astro', diff --git a/packages/starpod/src/layouts/Layout.astro b/packages/starpod/src/layouts/Layout.astro index ba36cc08..74a95dfe 100644 --- a/packages/starpod/src/layouts/Layout.astro +++ b/packages/starpod/src/layouts/Layout.astro @@ -5,7 +5,7 @@ import { Schema } from 'astro-seo-schema'; import SpeedInsights from '@vercel/speed-insights/astro'; -import Breadcrumbs from '../components/Breadcrumbs.astro'; +import Breadcrumbs from 'virtual:starpod/components/Breadcrumbs'; import Dots from 'virtual:starpod/components/Dots'; import Hosts from 'virtual:starpod/components/Hosts'; import InfoCard from 'virtual:starpod/components/InfoCard'; From 61e0729c03081af12604dd97b5fe91eab4220657 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Mon, 31 Aug 2026 08:38:21 -0400 Subject: [PATCH 2/2] Drop legacy mask-icon and msapplication-TileColor tags and assets Safari has ignored mask-icon in favor of the regular favicon since Safari 12, and msapplication-TileColor only ever applied to IE11/legacy Edge Start-menu tiles. Remove both tags from the Layout along with the root site's now-unreferenced safari-pinned-tab.svg, mstile-150x150.png, and browserconfig.xml. This also removes the fork's only reason to customize these colors. Co-Authored-By: Claude Fable 5 --- packages/starpod/src/layouts/Layout.astro | 2 -- public/browserconfig.xml | 9 -------- public/mstile-150x150.png | Bin 5049 -> 0 bytes public/safari-pinned-tab.svg | 26 ---------------------- 4 files changed, 37 deletions(-) delete mode 100644 public/browserconfig.xml delete mode 100644 public/mstile-150x150.png delete mode 100644 public/safari-pinned-tab.svg diff --git a/packages/starpod/src/layouts/Layout.astro b/packages/starpod/src/layouts/Layout.astro index 74a95dfe..8ada5b8d 100644 --- a/packages/starpod/src/layouts/Layout.astro +++ b/packages/starpod/src/layouts/Layout.astro @@ -67,8 +67,6 @@ const description = Astro.props.description ?? starpodConfig.description; - - - - - - - #da532c - - - diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png deleted file mode 100644 index d81d0d09220551e6624c9d652aa10b637ceb174d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5049 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 - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - - -