From cf917a901086e6d6afe5fc506f2efa7bf77c675a Mon Sep 17 00:00:00 2001 From: svemagie <869694+svemagie@users.noreply.github.com> Date: Mon, 20 Apr 2026 19:20:16 +0200 Subject: [PATCH] Fix Mastodon/Bsky duplicate replies in webmentions.js webmentions.js was adding NEW cards for Mastodon replies even when Alpine had already rendered them, because the client-side filter didn't mirror the Nunjucks build-time fed.brid.gy exclusion rule. Pass mastodon-active + bsky-url as data attributes on the webmentions container div, then filter out fed.brid.gy sourced Mastodon replies and bsky.app/brid.gy/bluesky Bluesky replies from regularItems when the corresponding Alpine component is active. Co-Authored-By: Claude Sonnet 4.6 --- _includes/components/webmentions.njk | 2 ++ js/webmentions.js | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/_includes/components/webmentions.njk b/_includes/components/webmentions.njk index fd10de6..82b24a1 100644 --- a/_includes/components/webmentions.njk +++ b/_includes/components/webmentions.njk @@ -12,6 +12,8 @@ data-target="{{ absoluteUrl }}" data-domain="{{ site.webmentions.domain }}" data-buildtime="{{ buildTimestamp }}" + data-mastodon-active="{{ 'true' if mastodonInstance else '' }}" + data-bsky-url="{{ bskySyndUrl }}" class="hidden"> {# Detect Bluesky syndication URL here — needed to show section even without webmentions #} diff --git a/js/webmentions.js b/js/webmentions.js index 2ed43c1..04a8efd 100644 --- a/js/webmentions.js +++ b/js/webmentions.js @@ -10,6 +10,8 @@ const target = container.dataset.target; const domain = container.dataset.domain; const buildTime = parseInt(container.dataset.buildtime, 10) || 0; + const mastodonActive = container.dataset.mastodonActive === 'true'; + const bskyUrl = container.dataset.bskyUrl || ''; if (!target || !domain) return; @@ -66,7 +68,15 @@ // Separate owner replies (threaded under parent) from regular interactions var ownerReplies = allChildren.filter(function(wm) { return wm.is_owner && wm.parent_url; }); - var regularItems = allChildren.filter(function(wm) { return !wm.is_owner && !isSelfBsky(wm); }); + var regularItems = allChildren.filter(function(wm) { + if (wm.is_owner || isSelfBsky(wm)) return false; + var src = (wm['wm-source'] || '').toLowerCase(); + var authorUrl = ((wm.author && wm.author.url) || '').toLowerCase(); + // Mirror Nunjucks build-time filters: skip platform replies handled by Alpine + if (mastodonActive && src.includes('fed.brid.gy')) return false; + if (bskyUrl && (src.includes('bsky.app') || src.includes('brid.gy/bluesky') || authorUrl.includes('bsky.app'))) return false; + return true; + }); let mentionsToShow; if (hasBuildTimeSection) {