WebMentions & Social Bridging ¶
markata-go supports the IndieWeb WebMention protocol for connecting your static site to the decentralized social web. This includes:
- Outgoing WebMentions: Automatically notify sites you link to
- Social Media Bridging: Receive likes, reposts, and replies from Twitter, Bluesky, Mastodon, and more
Quick Start ¶ #
Enable WebMentions in your markata-go.toml:
[markata-go.webmentions]
enabled = true
# For outgoing mentions
outgoing = true
# For social media bridging
[markata-go.webmentions.bridges]
enabled = true
bluesky = true
twitter = true
mastodon = true
Outgoing WebMentions ¶ #
When you link to external sites in your posts, markata-go can automatically send WebMentions to those sites (if they support the protocol).
How It Works ¶ #
- During build, markata-go scans your posts for external links
- For each link, it discovers the target site’s WebMention endpoint
- It sends a notification: “Hey, this URL linked to you!”
- The target site can then display your link/comment
Configuration ¶ #
[markata-go.webmentions]
enabled = true
outgoing = true
# HTTP request timeout
timeout = "30s"
# Max concurrent requests
concurrent_requests = 5
# Cache directory to avoid re-sending
cache_dir = ".cache/webmentions"
# Custom User-Agent string
user_agent = "MySite/1.0 (WebMention; +https://mysite.com)"
Caching ¶ #
Sent WebMentions are cached to avoid re-sending on every build. The cache is stored in the configured cache_dir as JSON.
Social Media Bridging ¶ #
Social media bridging allows you to receive interactions from Twitter, Bluesky, Mastodon, and other platforms as WebMentions. This is powered by services like Bridgy Fed.
Supported Platforms ¶ #
| Platform | Interactions | Detection |
|---|---|---|
| Bluesky | Likes, reposts, replies | bsky.app URLs, Bridgy |
| Twitter/X | Likes, retweets, replies | twitter.com/x.com URLs |
| Mastodon | Favorites, boosts, replies | Fediverse patterns |
| GitHub | Stars, comments, issues | github.com URLs |
| Flickr | Favorites, comments | flickr.com URLs |
Setting Up Bridging ¶ #
- Sign up for webmention.io to receive incoming mentions
- Connect Bridgy Fed to your social accounts at fed.brid.gy
- Configure markata-go:
[markata-go.webmentions]
enabled = true
webmention_io_token = "your_token_here"
[markata-go.webmentions.bridges]
enabled = true
bridgy_fediverse = true
# Enable specific platforms
bluesky = true
twitter = true
mastodon = true
github = true
flickr = false
Platform Detection ¶ #
markata-go automatically detects the source platform of incoming WebMentions by analyzing:
- URL patterns:
brid.gy/publish/bluesky,bsky.app, etc. - Domain matching: Known Mastodon instances, GitHub, etc.
- Content patterns: Platform-specific indicators in mention content
Each detected mention is enriched with:
- Platform name: “bluesky”, “twitter”, “mastodon”, etc.
- Handle: Platform-specific username (e.g.,
@alice.bsky.social) - Original URL: Link back to the original interaction
Filtering Bridged Mentions ¶ #
You can filter incoming mentions by platform, interaction type, or content:
[markata-go.webmentions.bridges.filters]
# Only accept from these platforms
platforms = ["bluesky", "mastodon"]
# Only accept these interaction types
# Options: "like", "repost", "reply", "bookmark", "mention"
interaction_types = ["like", "repost", "reply"]
# Minimum content length for replies
min_content_length = 10
# Block specific domains
blocked_domains = ["spam-site.com", "bad-actor.net"]
Template Integration ¶ #
Display WebMentions in your templates:
{% if post.webmentions %}
<section class="webmentions">
<h3>Reactions</h3>
{% for mention in post.webmentions %}
<article class="webmention webmention--{{ mention.platform }}">
<!-- Platform badge -->
{% if mention.platform != "web" %}
<span class="platform-badge">
{% if mention.platform == "bluesky" %}Bluesky
{% elif mention.platform == "twitter" %}Twitter
{% elif mention.platform == "mastodon" %}Mastodon
{% elif mention.platform == "github" %}GitHub
{% endif %}
</span>
{% endif %}
<!-- Author info -->
<div class="author">
{% if mention.author.photo %}
<img src="{{ mention.author.photo }}" alt="{{ mention.author.name }}">
{% endif %}
<a href="{{ mention.author.url }}">
{{ mention.handle | default(mention.author.name) }}
</a>
</div>
<!-- Interaction type -->
{% if mention.wm_property == "like-of" %}
<p>Liked this post</p>
{% elif mention.wm_property == "repost-of" %}
<p>Reposted this post</p>
{% elif mention.wm_property == "in-reply-to" %}
<blockquote>{{ mention.content.text }}</blockquote>
{% endif %}
<!-- Link to original -->
{% if mention.original_url %}
<a href="{{ mention.original_url }}">View on {{ mention.platform }}</a>
{% endif %}
</article>
{% endfor %}
</section>
{% endif %}
Platform-Specific Styling ¶ #
/* Platform colors */
.platform-badge--bluesky { background: #0085ff; }
.platform-badge--twitter { background: #1da1f2; }
.platform-badge--mastodon { background: #6364ff; }
.platform-badge--github { background: #333; }
/* Platform borders */
.webmention--bluesky { border-left: 3px solid #0085ff; }
.webmention--twitter { border-left: 3px solid #1da1f2; }
.webmention--mastodon { border-left: 3px solid #6364ff; }
.webmention--github { border-left: 3px solid #333; }
Fetching WebMentions ¶ #
WebMentions are fetched from webmention.io and cached locally. The build process reads from the cache, so you need to periodically fetch fresh mentions.
Fetching with CLI ¶ #
# Fetch all webmentions for your site
markata-go webmentions fetch
# The mentions are saved to .cache/webmentions/received_mentions.json
Environment Variable ¶ #
You can set your webmention.io token via environment variable instead of config:
export WEBMENTION_IO_TOKEN="your_token_here"
markata-go webmentions fetch
Automated Fetching ¶ #
Set up a cron job or CI workflow to fetch mentions regularly:
# .github/workflows/fetch-webmentions.yml
name: Fetch WebMentions
on:
schedule:
- cron: '0 */6 * * *' # Every 6 hours
workflow_dispatch:
jobs:
fetch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fetch webmentions
run: markata-go webmentions fetch
env:
WEBMENTION_IO_TOKEN: ${{ secrets.WEBMENTION_IO_TOKEN }}
- name: Commit cache
run: |
git config user.name github-actions
git config user.email [email protected]
git add .cache/webmentions/
git diff --staged --quiet || git commit -m "chore: update webmention cache"
git push
Displaying Counts on Post Cards ¶ #
The default theme includes a webmention counts partial that shows like/repost/reply counts on post cards.
Including the Partial ¶ #
Add to your card templates (e.g., article-card.html):
<article class="article-card">
<a href="{{ post.Href }}">
<h3>{{ post.Title }}</h3>
<p>{{ post.Description }}</p>
</a>
<footer>
<time>{{ post.Date.Format "Jan 2, 2006" }}</time>
{% include "partials/webmention-counts.html" %}
</footer>
</article>
The Counts Partial ¶ #
The partials/webmention-counts.html partial renders compact counts:
{% if post.Extra.webmentions %}
{% set likes = post.Extra.webmentions|selectattr("WMProperty", "equalto", "like-of")|list|length %}
{% set reposts = post.Extra.webmentions|selectattr("WMProperty", "equalto", "repost-of")|list|length %}
{% set replies = post.Extra.webmentions|selectattr("WMProperty", "equalto", "in-reply-to")|list|length %}
{% if likes > 0 or reposts > 0 or replies > 0 %}
<div class="webmention-counts">
{% if likes > 0 %}<span class="wm-count wm-likes" title="Likes">{{ likes }}</span>{% endif %}
{% if reposts > 0 %}<span class="wm-count wm-reposts" title="Reposts">{{ reposts }}</span>{% endif %}
{% if replies > 0 %}<span class="wm-count wm-replies" title="Replies">{{ replies }}</span>{% endif %}
</div>
{% endif %}
{% endif %}
Styling Counts ¶ #
The default theme uses semantic color variables:
.webmention-counts {
display: flex;
gap: 0.75rem;
font-size: 0.875rem;
}
.wm-count {
display: inline-flex;
align-items: center;
gap: 0.25rem;
}
.wm-count::before {
font-size: 1rem;
}
.wm-likes::before { content: ""; color: var(--color-error); }
.wm-reposts::before { content: ""; color: var(--color-success); }
.wm-replies::before { content: ""; color: var(--color-primary); }
Engagement Leaderboard ¶ #
The webmentions_leaderboard plugin calculates top posts by engagement and makes the data available for analytics pages.
Enabling the Leaderboard ¶ #
The leaderboard plugin runs automatically when webmentions are present. No additional configuration needed.
Accessing Leaderboard Data ¶ #
In any Jinja-enabled page, access the leaderboard via config.Extra.webmention_leaderboard:
---
title: "Site Analytics"
jinja: true
---
# Content Analytics
{% if config.Extra.webmention_leaderboard %}
## Most Liked Posts
| Likes | Post |
|------:|------|
{% for entry in config.Extra.webmention_leaderboard.TopLiked %}| {{ entry.Likes }} | [{{ entry.Title }}]({{ entry.Href }}) |
{% endfor %}
## Most Discussed Posts
| Replies | Post |
|--------:|------|
{% for entry in config.Extra.webmention_leaderboard.TopReplied %}| {{ entry.Replies }} | [{{ entry.Title }}]({{ entry.Href }}) |
{% endfor %}
## Most Shared Posts
| Reposts | Post |
|--------:|------|
{% for entry in config.Extra.webmention_leaderboard.TopReposted %}| {{ entry.Reposts }} | [{{ entry.Title }}]({{ entry.Href }}) |
{% endfor %}
## Top Engaged Posts (Total)
| Total | Likes | Reposts | Replies | Post |
|------:|------:|--------:|--------:|------|
{% for entry in config.Extra.webmention_leaderboard.TopTotal %}| {{ entry.Total }} | {{ entry.Likes }} | {{ entry.Reposts }} | {{ entry.Replies }} | [{{ entry.Title }}]({{ entry.Href }}) |
{% endfor %}
---
## Site Totals
- **Total Likes:** {{ config.Extra.webmention_leaderboard.TotalLikes }}
- **Total Reposts:** {{ config.Extra.webmention_leaderboard.TotalReposts }}
- **Total Replies:** {{ config.Extra.webmention_leaderboard.TotalReplies }}
- **Total Mentions:** {{ config.Extra.webmention_leaderboard.TotalMentions }}
{% else %}
*No webmention data available.*
{% endif %}
Leaderboard Data Structure ¶ #
| Field | Type | Description |
|---|---|---|
TopLiked |
[]LeaderboardEntry |
Top 20 posts by likes |
TopReposted |
[]LeaderboardEntry |
Top 20 posts by reposts |
TopReplied |
[]LeaderboardEntry |
Top 20 posts by replies |
TopTotal |
[]LeaderboardEntry |
Top 20 posts by total engagement |
TotalLikes |
int |
Site-wide total likes |
TotalReposts |
int |
Site-wide total reposts |
TotalReplies |
int |
Site-wide total replies |
TotalMentions |
int |
Site-wide total mentions |
Each LeaderboardEntry contains:
| Field | Type | Description |
|---|---|---|
Href |
string |
Post URL |
Title |
string |
Post title |
Likes |
int |
Number of likes |
Reposts |
int |
Number of reposts |
Replies |
int |
Number of replies |
Bookmarks |
int |
Number of bookmarks |
Mentions |
int |
Number of generic mentions |
Total |
int |
Total engagement |
Full Configuration Reference ¶ #
[markata-go.webmentions]
# Enable the webmentions plugin
enabled = true
# Send outgoing webmentions when linking to external sites
outgoing = true
# HTTP request timeout for sending/receiving
timeout = "30s"
# Directory to cache sent webmentions (avoids re-sending)
cache_dir = ".cache/webmentions"
# Maximum concurrent HTTP requests
concurrent_requests = 5
# User-Agent string for HTTP requests
user_agent = "markata-go/1.0 (WebMention; +https://github.com/WaylonWalker/markata-go)"
# API token for webmention.io (for receiving mentions)
webmention_io_token = ""
[markata-go.webmentions.bridges]
# Enable social media bridging detection
enabled = false
# Use Bridgy Fediverse for bridging
bridgy_fediverse = true
# Platform toggles
bluesky = true
twitter = true
mastodon = true
github = true
flickr = false
[markata-go.webmentions.bridges.filters]
# Limit to specific platforms (empty = all enabled)
platforms = []
# Limit to specific interaction types (empty = all)
# Options: "like", "repost", "reply", "bookmark", "mention"
interaction_types = []
# Minimum content length for replies
min_content_length = 0
# Block mentions from these domains
blocked_domains = []
Troubleshooting ¶ #
WebMentions not being sent ¶ #
- Ensure
enabled = trueandoutgoing = true - Check that target sites have WebMention endpoints
- Review the cache directory for sent status
- Check HTTP timeout settings
Bridged mentions not appearing ¶ #
- Verify your webmention.io token is correct
- Check that Bridgy is connected to your social accounts
- Ensure the platform is enabled in
bridgesconfig - Check filters aren’t blocking the mentions
Platform not detected correctly ¶ #
The platform detection uses URL patterns. If a mention isn’t being detected:
- Check the source URL in the raw WebMention data
- Ensure the platform is enabled in config
- File an issue if detection should be improved
Resources ¶ #
- WebMention Spec
- Bridgy Fed - Social media bridging
- webmention.io - Hosted WebMention receiver
- IndieWeb Wiki