{% extends "base.html" %} {% block content %}
Bridgy Fed turns your web site into its own fediverse account, visible in Mastodon and beyond. You can post, reply, like, repost, and follow fediverse accounts by posting on your site with microformats2 and sending webmentions. Bridgy Fed translates those posts into ActivityPub, and when people inside the fediverse respond, it sends those responses back to your site as webmentions.
This isn't syndication or POSSE! You don't need an account on Mastodon or anywhere else. Bridgy Fed makes your site a first class member of the fediverse. People there will see your posts directly from your site, and vice versa.
Bridgy Fed takes some technical know-how to set up, and there are simpler (but less powerful) alternatives. If you just want your site's posts to show up in the fediverse, without any other interactions, consider an RSS or Atom feed bot instead. Or, if you want to cross-post to an existing Mastodon account, try Bridgy.
Setup
Usage
About
Development
https://fed.brid.gy/
, including query parameters:/.well-known/host-meta /.well-known/webfinger
Here are instructions for a few common web servers:
WordPress (self-hosted): install the Safe Redirect Manager plugin, then add these entries:
/.well-known/host-meta* => https://fed.brid.gy/.well-known/host-meta*
/.well-known/webfinger* => https://fed.brid.gy/.well-known/webfinger*
.htaccess
file:RewriteEngine on RewriteBase / RewriteRule ^.well-known/(host-meta|webfinger).* https://fed.brid.gy/$0 [redirect=302,last](
RewriteEngine on
is optional if you already have it earlier in your .htaccess
. RewriteBase /
is optional if you don't have any other RewriteBase
directives, or if you put this RewriteRule
inside an existing RewriteBase /
section.)
nginx.conf
file, in the server
section:rewrite ^/\.well-known/(host-meta|webfinger).* https://fed.brid.gy$request_uri? redirect;
netlify.toml
file.
[[redirects]] from = "/.well-known/host-meta*" to = "https://fed.brid.gy/.well-known/host-meta:splat" status = 302 [[redirects]] from = "/.well-known/webfinger*" to = "https://fed.brid.gy/.well-known/webfinger" status = 302
Your site's fediverse profile comes from the microformats2 representative h-card on your site's home page. Here's a minimal example to set your name and a profile picture:
<span class="h-card"> <a rel="me" href="/">Alice Foo</a> <img class="u-photo" src="/me.jpg" /> </span>
If you want to set a header image, add a u-featured
image to your h-card, eg:
<img class="u-featured" src="/my-header.png" />
By default, your fediverse address will be @yourdomain.com@yourdomain.com
. Many services (eg Mastodon) default to only showing the username, so this generally shows up as just @yourdomain.com
in posts, and the full address appears on hover.
We recommend this for simplicity and predictability, for everyone else as well as you, but if you want a different username, you can set it by adding an acct:
u-url link inside your h-card with username@yourdomain.com
, eg:
<a class="u-url" href="acct:alice@yourdomain.com"></a>
If you've changed the representative h-card on your site's home page, and you want to update your profile in Mastodon to match, click the button next to your domain on your user page. Alternatively, you can send a webmention from your home page to https://fed.brid.gy/
.
Enter your domain here to see your user page. It shows your site's current status, recent interactions, remote follow UI, and links to your timeline feeds in various formats.
Create a post with the h-entry
microformat on your web site. Many web servers include this or compatible microformats automatically. The post can be a note, article, like, repost, reply, or follow. For example:
<div class="h-entry"> <p class="e-content">Two naked tags walk into a bar. The bartender exclaims, "Hey, you can't come in here without microformats, this is a classy joint!"</p> <a class="u-bridgy-fed" href="https://fed.brid.gy/"></a> </div>
Mastodon preserves HTML links and line breaks, but removes all other formatting and tags. Other fediverse sites vary in their HTML handling.
Then, include a link (optionally blank) to https://fed.brid.gy/
in that post and send Bridgy Fed a webmention. That webmention will trigger Bridgy Fed to forward your post into the fediverse. Your web server may send the webmention automatically if it supports them, or you can send it manually.
(The u-bridgy-fed
class isn't strictly necessary, but it's useful in some cases to prevent microformats2 parsers from interpreting the link as an implied u-url
.)
Only the ones you explicitly trigger with a webmention. Bridgy Fed doesn't automatically create posts in the fediverse based on your site's Atom feed, HTML, or anything else. It only create posts in the fediverse on an opt in basis, per post, via webmention.
Bridgy Fed currently supports at least these major fediverse apps:
...and work is ongoing to support these:
diaspora* is unlikely because they use their own federation protocol, not ActivityPub. Details.
Magic! Most major blog engines and CMSes are supported out of the box, no setup necessary. Bridgy Fed looks for microformats in your HTML, first the microformats2 e-content
class and then the legacy entry-content
class. It also understands more advanced microformats2 classes like in-reply-to
, u-like-of
, u-repost-of
, and u-photo
.
Bridgy Fed sends the full contents of all posts, specifically everything inside e-content
, to the fediverse. However, not all fediverse apps currently show the full contents of all posts.
For example, text-based posts fall into two broad buckets: short notes, eg tweets and toots, and longer articles, eg blog posts. In the IndieWeb, we differentiate based on whether the post has a title: articles generally have titles, notes don't.
Mastodon currently shows the full text of notes, but for articles, it only shows their titles and a link to the full article. This is because Mastodon and most other fediverse apps are designed primarily for smaller notes, not longer articles.
These can happen for a couple reasons. For articles, this is expected behavior, as described above. The link is a Bridgy Fed URL that redirects to the original post on your web site. This is because Mastodon requires ActivityPub (ie fediverse) object URLs to use the same domain that serves them, which in this case is fed.brid.gy. We know it's awkward; sorry for the ugliness!
Otherwise, this may be the invisible fed.brid.gy link that's required to trigger Bridgy Fed. Mastodon will show a preview of links even if their text is blank, so if your link is inside your e-content
microformats2 element, that's probably what's happening. You can prevent that by moving it outside of e-content
. It can go anywhere in your HTML!
Put the reply in a new post on your web site, and include a link to the fediverse post you're replying to with class u-in-reply-to
, as if you were publishing a normal IndieWeb reply. For example:
<div class="h-entry"> <p class="e-content">Highly entertaining. Please subscribe me to your newsletter.</p> <a class="u-in-reply-to" href="https://indieweb.social/@tchambers/109243684867780200"></a> <a class="u-bridgy-fed" href="https://fed.brid.gy/"></a> </div>
Favoriting and boosting are almost exactly the same as replying. The only difference is that you use u-like-of
for a favorite/like or u-repost-of
for a boost/repost.
<a class="u-like-of" href="https://octodon.social/@cwebber/109405439825087368"></a>
<a class="u-repost-of" href="https://prodromou.pub/@evan/109390803478257847"></a>
If your web site supports IndieAuth, go to your user page, click the Following link, then enter the address of the account you want to follow.
You can also follow someone by posting an IndieWeb follow on your site, including the u-follow-of
microformats2 class, and sending a webmention to Bridgy Fed. Your site may do that automatically if it supports webmentions. For example:
<div class="h-entry"> I'm now following <a class="u-follow-of" href="https://octodon.social/@cwebber">@cwebber@octodon.social</a>! <a class="u-bridgy-fed" href="https://fed.brid.gy/"></a> </div>This method doesn't require IndieAuth, and it can be automated.
Go to your user page, click the Following link, find the account you want to unfollow, and click the X next to their address. Like following, this requires your web site to support IndieAuth.
Use <img class="u-photo">
for the image in your post. For example:
<img class="u-photo" src="/full_glass.jpg" /> I love scotch. Scotchy scotchy scotch.
Use p-category
and link the hashtag to a fully qualified URL. (Any URL you want!) Fediverse sites like Mastodon will generally rewrite the link to point to a search for that hashtag on the local instance. For example:
<div class="h-entry"> <p class="e-content"> just setting up my feddr <a href="https://mysite.com/tag/throwback" class="p-category">#throwback</a> </p> </div>
The leading #
character on the hashtag text is optional. If you don't include the hashtag in e-content
, or include it but not inside an <a>
link, fediverse sites won't add the hashtag text or link themselves, but your post will still be indexed in searches for that hashtag.
Edit the post on your web site, then send another webmention to Bridgy Fed for it. Bridgy Fed will refetch the post and send an Update
activity for it to the fediverse.
First, delete the post on your web site, so that HTTP requests for it return 410 Gone or 404 Not Found. Then, send another webmention to Bridgy Fed for it. Bridgy Fed will refetch the post, see that it's gone, and send an Delete
activity for it to the fediverse.
If that HTML element has its own id, then sure! Just put the id in the fragment of the URL that you publish. For example, to publish the bar
post here:
<div id="a" class="h-entry">foo</div> <div id="b" class="h-entry">bar</div> <div id="c" class="h-entry">baz</div>
...just add the id to your page's URL in a fragment, e.g. http://site/post#b
here.
To receive likes, reposts, replies, @-mentions, and follows from the fediverse, just make sure your site accepts webmentions! Bridgy Fed translates those interactions and sends them to your site as webmentions. The source URL will usually be a proxy page on fed.brid.gy
. For best results, make sure your webmention handler detects and handles u-url
links.
Your user page has links to your fediverse timeline/feed, ie posts from people you follow, in HTML, Atom, and RSS formats. Add them to your feed reader or read them in your browser!
Yes! Your user page shows a feed of your notifications - mentions, replies, likes, reposts, follows, etc - in h-feed format, which you can subscribe to in any social reader. Let us know if you want other formats!
They can search for your web site in any Mastodon instance! Often you can just enter your domain, eg yourdomain.com
, in any Mastodon search box. If that doesn't work, try your full fediverse address, eg @yourdomain.com@yourdomain.com
. This can be finicky now and then, but it usually works.
Your user page has a "Following" link that shows you everyone on the fediverse who's currently following you. It also has a "remote follow" form that lets people enter their fediverse address and follow you directly.
This varies by fediverse app. For Mastodon, open your list of followers in Bridgy Fed and click on one to open their profile. Then, inside that Mastodon instance, search for your site's address, click on it in the search results, and you'll see your fediverse profile and all of your posts that were delivered to that instance. This may not be all of them, depending on how long and when people on that instance have been following you.
This general process should often work in other fediverse apps too.
Note: in Mastodon, each of your posts on a given instance will have a permalink inside that instance, eg mastodon.social/@snarfed.org@snarfed.org/109729052169033033, but those permalinks only go to Mastodon if you're logged into that instance. If you're not, they redirect to the original post on your site.
Yes! Add this line of HTML to each post that you publish with Bridgy Fed and want to be searchable, replacing [URL]
with that post's URL:
<link rel="alternate" type="application/activity+json" href="https://fed.brid.gy/r/[URL]">
Search is intentionally limited in Mastodon and much of the overall fediverse, so this won't index the full text of your posts, but it will make them show up in search results when you search for your post's full URL, which people commonly do in the fediverse to find and interact with posts.
Check out your user page! It detects and describes common problems with your setup, and it shows your recent interactions and detailed logs.
I'm Ryan Barrett. I'm just a guy who likes the web and owning my data.
Nothing! Bridgy Fed is small, and it doesn't cost much to run. We don't need donations, promise.
If you really want to contribute, file an issue or send a pull request, or donate to the IndieWeb!
Nothing! Bridgy Fed isn't a business, and never will be, so we don't have the same motivations to abuse your data that other services might. More concretely, Bridgy Fed won't ever send you email, it stores as little of your PII (personally identifiable information) as possible, and it never has access to any of your passwords.
I started thinking about bridging federated social networks and peer to peer networks when I discovered them in the early 2000s. I started talking about bridging them to the IndieWeb in 2016, led a session on it at IndieWeb Summit in July 2017, wrote up concrete designs soon after, started working on Bridgy Fed in August 2017, and launched it on October 22, 2017.
Bridgy Fed's terms of service are very simple. You agree not to deliberately attack, breach, or otherwise harm the service. If you manage to access private keys or other private data, you agree to report the vulnerability and not use or disclose that data.
Otherwise, you may use the service for any purpose you see fit. However, we may terminate or block your access for any reason, or no reason at all. (We've never done this, and we expect we never will. Just playing it safe.)
Do you an administer an instance or other service that Bridgy Fed interacts with? If you have any concerns or questions, feel free to file an issue!
Great! Please file it in GitHub. Thank you!
Oof. Thank you for reporting it! Please send details to security@brid.gy. We may provide monetary awards for reports of significant vulnerabilities, eg reading or modifying stored access tokens, if you follow these rules:
/admin/*
pages.
Otherwise, the code is open source, feel free to try to break in, let us know if you succeed!
Here are internal details on how Bridgy Fed translates user identity and events between protocols, including some like Nostr and Bluesky/AT Protocol that aren't launched here, or even fully implemented or thought through yet. Caveat hacker!
In the tables below, BF is Bridgy Fed, enhanced is users who have done extra setup for BF, basic is users who haven't. Green parts have been implemented and running here for years, the rest are still in the early design phase.
Here's how we (hope to) translate user identity between protocols. Specifically, each cell shows how a user in a given row is identified to the protocol in a given column.
Web | ActivityPub | AT Protocol | Nostr | |
---|---|---|---|---|
Web | - |
basic: @[domain]@web.brid.gy enhanced: @[domain]@[domain]
|
basic: [domain].web.brid.gy as handleenhanced: bare domain as handle code: did:plc , via BF
|
basic: [domain].web.brid.gy , as NIP-05enhanced: bare domain, via NIP-05 code: npub... public key, via BF |
AP | Fediverse profile URL | - | basic: [username].[instance].ap.brid.gy as handleenhanced: [username].[instance] domain as handle (unlikely?)code: did:plc , via BF
|
basic: [username].[instance].ap.brid.gy as NIP-05enhanced: [username].[instance] domain, via NIP-05 (unlikely?)code: npub... public key, via BF |
ATP | PDS web frontend profile URL (how will we get this?) | basic: @[handle]@bsky.brid.gy enhanced: @[handle]@[handle]
|
- | basic: [handle].bsky.brid.gy as NIP-05enhanced: bare handle, via NIP-05 code: npub... public key, via BF |
Nostr | NIP-05 domain or BF user page | basic: @[npub...]@nostr.brid.gy NIP-05: @[NIP-05]@nostr.brid.gy enhanced: @[NIP-05]@[NIP-05]
|
basic: [NIP-05].nostr.brid.gy as handleenhanced: bare NIP-05 domain as handle code: did:plc , via BF
|
- |
Here's how we (hope to) translate events and operations between protocols, both inbound to and outbound from Bridgy Fed.
Web | ActivityPub | AT Protocol | Nostr | |
---|---|---|---|---|
User discovery inbound | serve h-card on BF user page |
basic: serve WebFinger and AP actor on fed.brid.gy enhanced: user's site serves and redirects WebFinger to fed.brid.gy |
resolve DID, serve DID document with fed.brid.gy PDS | NIP-39 (kind 0) query to BF (or other?) relay |
User discovery outbound | Fetch home page, parse h-card |
look up WebFinger, fetch AP actor | resolve DID, subscribe to PDS repo, extract profile object? | discover user's relays with NIP-65, query NIP-39 to get profile |
Publish inbound | webmention to fed.brid.gy | deliver to fed.brid.gy inbox, user or shared | subscribe to user's PDS repo on fed.brid.gy | publish event to BF relay |
Publish outbound | serve on BF user page followings h-feed |
deliver to recipient's inbox | serve repo diff via sync XRPCs to subscribing BGSes |
serve to subscribers |
Follow inbound | users: UI on BF user page code: webmention with u-follow-of |
Follow activity delivered to BF user inbox |
receive sync.subscribeRepos ? |
user's client sends REQ to BF relay |
Follow outbound | webmention with BF proxy HTML page as source | deliver Follow to followee's inbox |
call sync.subscribeRepos on followee's PDS? |
discover followee's relay(s) with NIP-65, send them a REQ |
Response inbound | webmention to a BF proxy page | Create , Like , Announce delivered to BF user inbox |
response object received from a subscribed repo? (what if it's from a user we don't subscribe to?) |
NIP-10 response event received at BF relay or other relay |
Response outbound | same as follow outbound, with the corresponding response data type |
"It's complicated." ...well, at least a bit. There are different philosophies on how to architect request handling and error propagation in these kinds of server-to-server protocols.
One common bit of received wisdom is to handle all requests asynchronously, in the background. Do minimal request validation synchronously, if necessary, then return HTTP 202 (or 201) and enqueue the request in a background task queue to be processed offline. This is widespread in ActivityPub implementations, for example. Webmention even recommends it as a SHOULD!
Upon receipt of a POST request containing the source and target parameters, the receiver SHOULD verify the parameters (see Request Verification below) and then SHOULD queue and process the request asynchronously, to prevent DoS attacks.
It's a good idea, but it has drawbacks. Most importantly, it hides errors. Sending side implementations always receive HTTP 202 responses, even when their requests fail in the background, and there's no standard or widely implemented way to get more information or debug. Webmention nods to this and says receivers can return a per-request status URL in the Location
response header, but that's not widely implemented, and ActivityPub has no corresponding mechanism. This makes development and interop materially harder, especially in these protocols' loosely connected ecosystems. Mastodon's issue tracker, for example, is full of issues complaining "Mastodon isn't working with my code, but I can't tell why!"
Bridgy Fed currently takes a compromise position. It handles most requests synchronously, blocks on delivering them to the destination protocol, and propagates any errors back to the sender with the appropriate HTTP response status code and body (often JSON). Delivering posts to ActivityPub followers is one exception; it currently delivers to inboxes serially, so it often takes many minutes, which is uncomfortably long for many HTTP clients.
Converting to webmention is another exception. Bridgy Fed uses webmentions and microformats2 to provide social interactions for web sites, but unlike with other protocols, it doesn't require web sites to support them. So, Bridgy Fed doesn't currently convert webmention failures (or lack of support) to errors in other protocols. It records those failures, and shows them in the UI on your user page, but returns success to the sending side in its own protocol.