| 1 | --- |
| 2 | export const prerender = false; |
| 3 | |
| 4 | import PageLayout from "@/layouts/Base.astro"; |
| 5 | |
| 6 | const meta = { |
| 7 | title: "/blogroll", |
| 8 | description: "A collection of RSS feeds I'm subscribed to", |
| 9 | }; |
| 10 | |
| 11 | // Fetch the feeds data |
| 12 | const response = await fetch("https://feeds.stevedylan.dev/api/subscriptions"); |
| 13 | const data = await response.json(); |
| 14 | |
| 15 | // Sort subscriptions by title |
| 16 | const sortedFeeds = data.subscriptions.sort((a, b) => |
| 17 | a.title.localeCompare(b.title), |
| 18 | ); |
| 19 | --- |
| 20 | |
| 21 | <PageLayout meta={meta}> |
| 22 | <div class="space-y-6"> |
| 23 | <h1 class="title">/blogroll</h1> |
| 24 | <p> |
| 25 | Help build a blog network with me! Check out some of the people I follow |
| 26 | below, and if you end up following them too, create a <a |
| 27 | href="https://indieweb.org/blogroll" |
| 28 | class="style-link" |
| 29 | target="_blank" |
| 30 | rel="noreferrer">/blogroll</a |
| 31 | > page of your own with your list of people! |
| 32 | </p> |
| 33 | <h2 class="text-xl font-semibold text-accent-2">Links</h2> |
| 34 | <ul |
| 35 | class="list-none pl-0 space-y-4 sm:grid sm:grid-cols-2 sm:gap-y-4 sm:space-y-0" |
| 36 | > |
| 37 | { |
| 38 | sortedFeeds.map((feed) => ( |
| 39 | <li> |
| 40 | <a |
| 41 | href={feed.site_url} |
| 42 | target="_blank" |
| 43 | rel="noopener noreferrer" |
| 44 | class="inline-flex items-center gap-2" |
| 45 | > |
| 46 | {feed.favicon_url && ( |
| 47 | <img |
| 48 | src={feed.favicon_url} |
| 49 | alt={`Favicon for ${feed.title}`} |
| 50 | width="16" |
| 51 | height="16" |
| 52 | loading="lazy" |
| 53 | class="favicon w-4 h-4 rounded-sm" |
| 54 | onerror="this.style.display='none';this.nextElementSibling.style.display='inline-block'" |
| 55 | /> |
| 56 | )} |
| 57 | <svg |
| 58 | xmlns="http://www.w3.org/2000/svg" |
| 59 | width="16" |
| 60 | height="16" |
| 61 | viewBox="0 0 256 256" |
| 62 | class="favicon-fallback w-4 h-4" |
| 63 | style={feed.favicon_url ? "display:none" : ""} |
| 64 | aria-hidden="true" |
| 65 | > |
| 66 | <path |
| 67 | fill="currentColor" |
| 68 | d="M216 40H40a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h176a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16m0 16v32H40V56Zm0 144H40v-96h176z" |
| 69 | /> |
| 70 | </svg> |
| 71 | {feed.title} |
| 72 | </a> |
| 73 | </li> |
| 74 | )) |
| 75 | } |
| 76 | </ul> |
| 77 | <h2 class="text-xl font-semibold text-accent-2 pt-8">API</h2> |
| 78 | <p> |
| 79 | I'm currently using my own RSS aggregator and reader called <a |
| 80 | href="https://andromeda.build/apps/feeds/" |
| 81 | target="_blank" |
| 82 | rel="noopener noreferrer" |
| 83 | class="style-link">Feeds</a |
| 84 | > to manage my feeds, which inlcudes an API to programmatically share them as |
| 85 | a list. |
| 86 | </p> |
| 87 | <pre |
| 88 | class="whitespace-pre-wrap break-all"><code># JSON |
| 89 | curl https://feeds.stevedylan.dev/feeds?format=json |
| 90 | |
| 91 | # OPML File |
| 92 | curl https://feeds.stevedylan.dev/feeds?format=opml -o feed.opml</code></pre> |
| 93 | </div> |
| 94 | </PageLayout> |