/friends

Changelog

Here's a rough diary of all the updates I've been making to slashfriends.org. New sites show up here automatically as soon as they're added to the directory.

Thursday, August 13, 2026

🔗 1 new site added

Welcome to danielhadaway.dev.

Wednesday, August 12, 2026

🔗 2 new sites added

Welcome to andysommer.com, and juandavidcampolargo.com.

📸 real faces on the cards

A bunch of /friends cards here showed a plain gray letter instead of a person, because the site has no favicon. Other sites had tiny default icons. (Even my own site had an American flag icon, which I think is cool.)

But this directory is about people, and faces are better!

So today I fired up some agents to go looking for real photos. I think we'll only share pictures you already published yourself, on your homepage, your about page, or a social profile your own site links to. The agents cropped each one square, ran some sort of face-center algo on the images, then emailed everyone to ask permission before posting. Here's the actual email:

Within a few hours, 15 of the 27 people I emailed had clicked yes, and nobody has said no. Here are a few of the swaps:

anne-laure.net new face icon
anne-laure.net
quinnsaysyes.com new face icon
quinnsaysyes.com
chriscarey.vision new face icon
chriscarey.vision
nickgray.net old iconnickgray.net new face icon
nickgray.net
sujeetbhalerao.com old iconsujeetbhalerao.com new face icon
sujeetbhalerao.com
ryanbed.org old iconryanbed.org new face icon
ryanbed.org

For nerds: we used OpenCV's Haar-cascade face detection to find and center each face, then saved 128px WebP icons. Approvals are one-click tokenized links on a Cloudflare Worker, with the decisions in a D1 database, replacement photos uploading to R2, and the permission emails going out through Cloudflare Email Service. An approved photo activates instantly, no redeploy.

Tuesday, August 11, 2026

🕸️ the IndieWeb got here first

It turns out /friends pages are not my idea. The IndieWeb community has been making personal websites that link to each other for years, and their wiki already lists /friends as a kind of page you can have. Lukas Rosenstock emailed me to point this out, and I think someone over there added slashfriends.org to the wiki. I have a profile there now too. Great community. Go look.

Lukas also pointed me at rel="friend", a small attribute you can put on a link to say this is a person I actually know. Nice idea, and you should add it if you like it. I am not going to require it. The only thing you need to get listed here is a real page at yourdomain.com/friends.

Monday, August 10, 2026

🔗 1 new site added

Welcome to chriscarey.vision.

🖼️ fresher favicons

Two people updated their site's favicon and the directory kept showing the old one. Zach Ware's card showed a purple square when his site has an American flag, and K. Elizabeth Coggins's showed a generic gray cube instead of her photo.

Turns out I was getting every icon from Google's favicon service, and Google's copy can go stale for months. DuckDuckGo has an icon service too, and it fetches your site's actual current favicon. So now I ask DuckDuckGo first and only fall back to Google when DuckDuckGo comes up empty. I tested it by hammering their service with all 87 sites at once from my server, four times in a row, and it never once complained.

Nerdy detail: DuckDuckGo hands back your original favicon file, which is what makes it fresh, but originals can be huge. One site's icon is a 108KB PNG. Anything over 30KB still gets Google's tiny resized version instead, so the homepage stays fast.

📋 failed submissions were invisible. fixed.

A friend emailed me: he built a /friends page, submitted it here, and got rejected. News to me. When a submission failed, my system told the submitter and then forgot it ever happened. He only got listed because he happened to know me.

His page was real, and good. But his site builds itself entirely with JavaScript, so my crawler sees an empty page no matter what. I added him by hand, and now every rejected submission gets logged with the reason, and a nightly email shows me what bounced. If the system turns someone away by mistake, I'll actually know about it.

Friday, August 7, 2026

🧹 cleaned up some little stuff

Cleaned up some little stuff behind the scenes. More updates soon.

Thursday, July 23, 2026

🔗 4 new sites added

Welcome to aniawysocka.com, aidenfishbein.com, collinwmartin.com, and adambuice.com.

Wednesday, July 22, 2026

🔗 3 new sites added

Welcome to realbenalbert.com, davidshapiro.co, and claireboston.net.

Tuesday, July 21, 2026

Monday, July 20, 2026

Saturday, July 18, 2026

🔗 2 new sites added since July 17

Welcome to victoriagaddis.com, and nejimaki.me.

Thursday, July 16, 2026

Wednesday, July 15, 2026

🔗 3 new sites added

Welcome to willmitchell.com, roadieriches.com, and carlosarthur.com.

🚧 a blog post snuck in

A 2012 blog post got listed as a /friends page this morning. Someone submitted a site whose WordPress guessed at the URL instead of 404ing, so /friends quietly redirected to an old post that happened to be titled "Friends". It was a real page with real links out, so every check I had passed it.

I was only checking that the redirect landed on a URL with "friends" somewhere in it, and /2012/07/friends.html clears that bar. Now the redirect has to land on an actual /friends page, and anything else gets held for me to look at. Redirecting to www still works fine, and so does Blogger and Substack putting their pages at /p/friends.

🤖 a robot reads the weird ones

When a submission gets held and its page doesn't link back to me, I now have an AI read the page and decide whether it's genuinely a list of other people's websites or just an essay about friendship. If it's clearly not a /friends page, you get told right away instead of waiting on me. Nothing gets saved, so you can fix your page and resubmit immediately.

It only gets to say no, never yes. Anything it thinks is fine still comes to me to look at, because a wrong no just means you email me and I sort it out, while a wrong yes would sit on the homepage with nobody watching. It also has to actually be able to read your page. If your /friends page builds itself with JavaScript, my crawler sees an empty page, and "I can't read this" is not the same as "this is bad". Those still come to me.

If your page links back to me, none of this runs at all. You've already told me what the page is.

Tuesday, July 14, 2026

✍️ I wrote an article about /friends pages

I wrote an article about /friends pages over on my other website, The Friendship Recession. It's about what a /friends page actually is, why I made one for myself, and why I liked the idea enough to go build this whole directory.

The Friendship RecessionWhy Every Personal Website Needs a /friends PageA /friends page is a list of the people you know and like, at yourdomain.com/friends. Here's why I built one, why I made a directory of them, and how to make yours.Read the article →

You don't have to read it. But I made a bunch of illustrations for it, and those I do want to show off.

An ink illustration of a crowd of little website cards with legs, each one showing a domain and a /friends heading, milling around together.
What all of our /friends pages hanging out at a party looks like in my imagination.
Large type reading
I just liked this quote. And the idea that “personal websites are the name tags of the Internet.”
An ink illustration of website cards with yellow bookmark ribbons, scattered across a page and threaded together with fine lines.
I used this one for the featured image. Sort of an inter-web of all our /friends pages.

🕵️ catching fake /friends pages

I now check that your /friends page is actually a page. Some sites answer every URL with the same thing, so /friends looked real but was just a copy of their homepage. Now I also ask the site for a URL that can't possibly exist. If that comes back looking the same as /friends, then there's nothing there, and the submission doesn't get listed.

Nerdy detail: it compares the visible text of the two pages, not the raw HTML. Hashing the markup doesn't work, because one of the sites I caught this way hands back slightly different bytes on every single request. Strip the tags out and the two pages are word for word identical.

✂️ long domains were breaking the cards

Long domain names were wrapping onto two lines, which made their card taller than everything around it. They now stay on one line and trail off with an ellipsis, like trevormckendrick…

Monday, July 13, 2026

🎨 redesigned the homepage cards

I gave the cards on the homepage and the about page a new look. The old ones had a big yellow banner and a white frame around each favicon. The new ones lead with the domain in bold, show the favicon cleanly with no frame, and sit on a hard black drop shadow that pops when you hover over them. The FEATURED badge moved to a little ribbon stitched into the corner.

Before
reubeningber.com/friendsFEATURED

Friends | Reuben Ingber


These are some of my internet friends.

molodtsov.me/friends

The blogroll of websites I love reading


A blog roll of websites I enjoy following.

After
FEATURED
reubeningber.com/friends

Friends | Reuben Ingber

These are some of my internet friends.

molodtsov.me/friends

The blogroll of websites I love reading

A blog roll of websites I enjoy following.

🔗 linked friends from my blog

I told the first people who added a /friends page that I'd link back to them from my personal blog, and today I did. A fresh batch of you is now listed over on nickgray.net/friends.

Sunday, July 12, 2026

✨ redesigned the /about page

The about page got a full redesign. A bigger hero, cards showing real /friends pages from the directory, a better AI prompt section, and a bunch of mobile fixes.

🧹 the great favicon outage

Every favicon on the site broke this morning. A caching bug in my icon proxy was corrupting the images, so every site showed a blank square. Fixed, and I wrote a postmortem.

Here's how favicons work here, because it's kind of neat. Every icon is proxied through this site at /fav/yourdomain.com and cached at the edge for a day, so your browser never talks to Google's favicon service directly. And when a site has no favicon at all, Google returns a tiny generic globe. I detect that and swap in a yellow monogram tile with the first letter of the domain instead. Here are some from the directory:

danielhadaway.dev faviconjuandavidcampolargo.com faviconandysommer.com faviconchriscarey.vision faviconzgware.com faviconkelizabethcoggins.com favicon0xded.dev faviconrandymlong.com faviconmeghanraftery.com faviconlukasrosenstock.net faviconhaktheplanet.org faviconthatjimmy.com favicon

🛡️ spam guard

Sketchy submissions now get held as pending, and I approve or deny them from an email. I also turned on Cloudflare Turnstile on the submit form. Real people only, please.

🎲 better browsing

The random page button got smarter. "Next page" now cycles through every site in order, so you see each one exactly once per lap. And sites that block iframes get a nice fallback card instead of an error. Nerdy detail: before embedding a site, my crawler reads its X-Frame-Options and Content-Security-Policy headers to see if the site allows being shown in an iframe. Sites that say no get the card instead, and the card even quotes the exact header that blocked it.

🔍 SEO tune-up

Canonical URLs, per-page descriptions, JSON-LD structured data, and 301 redirects to kill trailing slashes. Boring but important. Robots deserve clean URLs too.

🧰 small stuff

Added a proper confirmation page after you submit your site. Put browse in the nav. Added privacy-friendly analytics from Plausible.

Saturday, July 11, 2026

🏠 new homepage cards

The homepage got brand new cards: a yellow banner, a stamp-framed favicon, and a hard black border. I call the design "Banner bold" and it took five rounds of mockups to get there.

⭐ the FEATURED badge

Sites whose /friends page links back here (or to my site) now get a little FEATURED badge on their card. Linking out is generous. Linking back is friendly.

🤖 copy-paste AI prompt

There's now a prompt you can copy and hand to an AI agent, and it will build your /friends page for you. It's at the bottom of the homepage and on the about page.

📡 for the robots

Added an RSS feed at /feed.xml, a public JSON dump at /sites.json, an llms.txt for the AI agents, a sitemap, a social share image, and a proper 404 page. The machines are well fed. Here's that share image: slashfriends.org social share image

⚡ speed obsession

This site has no JavaScript framework, and all the CSS gets inlined into the page at build time, so there are zero render-blocking requests. Combined with the same-origin favicon proxy, the whole thing loads in about one round trip. PageSpeed likes it a lot.

Friday, July 10, 2026

🔧 crawler fixes for Substack

Some Substack-hosted /friends pages were failing verification because Substack blocks robot-looking requests. My checker now sends a browser-flavored request and retries politely on 429 and 403 errors. If your submission failed before, try again.

While I'm here, some detail on the crawler: it visits every listed site once a day to make sure the page is still live, pulls the title and a short excerpt for the directory card, decodes messy HTML entities, and notices when a /friends page links back here. Sites that link back get the FEATURED badge on the homepage.

Thursday, July 9, 2026

🔗 2 new sites added

Welcome to nickgray.net, and quinnsaysyes.com. I built this directory, so by default I guess my /friends page was the first to be included. Nepotism!

🚀 launched slashfriends.org

Day one! I built and launched this directory, and the whole thing runs on Cloudflare:
  • Cloudflare Workers serves every page. The site is built with Astro and deploys as a single Worker.
  • 🗄️ D1 is the little SQL database that holds every listing.
  • Cron Triggers re-check every site daily to make sure the pages are still live.
  • 🛡️ Turnstile keeps spam bots off the submit form, with no annoying puzzles for humans.
  • 📬 Email Routing and Email Sending handle the confirmation emails.
I'm a big fan of their developer tools. Highly recommended.