From 55927722ccbc6e910aa19e9a2d64a51a6ca148cd Mon Sep 17 00:00:00 2001 From: Ricardo Date: Sun, 15 Mar 2026 09:23:41 +0100 Subject: [PATCH] fix: filter out self-mentions from webmentions display Owner replies sent via webmention-sender appear as webmentions on the owner's own posts, showing the reply as a top-level entry instead of threaded. Filter out any webmention whose source URL starts with the site URL, in both build-time (eleventy.config.js) and client-side (webmentions.js) rendering paths. Confab-Link: http://localhost:8080/sessions/184584f4-67e1-485a-aba8-02ac34a600fe --- eleventy.config.js | 10 ++++++++-- js/webmentions.js | 24 +++++++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/eleventy.config.js b/eleventy.config.js index 77726dd..76394b8 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -820,8 +820,14 @@ export default function (eleventyConfig) { urlsToCheck.add(`${siteUrl}${contentUrl}`.replace(/\/$/, "")); } - // Filter merged data matching any of our URLs - const matched = merged.filter((wm) => urlsToCheck.has(wm["wm-target"])); + // Filter merged data matching any of our URLs, excluding self-mentions + // (owner replies sent via webmention-sender appear as webmentions on own posts) + const matched = merged.filter((wm) => { + if (!urlsToCheck.has(wm["wm-target"])) return false; + const source = wm["wm-source"] || wm.url || ""; + if (source.startsWith(siteUrl)) return false; + return true; + }); // Deduplicate cross-source: same author + same interaction type = same mention // (webmention.io and conversations API may both report the same like/reply) diff --git a/js/webmentions.js b/js/webmentions.js index ca20a0c..2f1a1ba 100644 --- a/js/webmentions.js +++ b/js/webmentions.js @@ -13,6 +13,11 @@ if (!target || !domain) return; + // Extract site origin for filtering self-mentions + // (owner replies sent via webmention-sender appear as webmentions on own posts) + var siteOrigin = ''; + try { siteOrigin = new URL(target).origin; } catch(e) {} + // Use server-side proxy to keep webmention.io token secure // Fetch both with and without trailing slash since webmention.io // stores targets inconsistently (Bridgy sends different formats) @@ -55,6 +60,14 @@ function processWebmentions(allChildren) { if (!allChildren || !allChildren.length) return; + // Filter out self-mentions (may exist in older cached data) + allChildren = allChildren.filter(function(wm) { + if (!siteOrigin) return true; + var source = wm['wm-source'] || wm.url || ''; + return !source.startsWith(siteOrigin); + }); + if (!allChildren.length) return; + let mentionsToShow; if (hasBuildTimeSection) { // Build-time section exists — deduplicate against what's actually rendered @@ -155,6 +168,13 @@ const wmItems = [...(wmData1.children || []), ...(wmData2.children || [])]; const convItems = [...(convData1.children || []), ...(convData2.children || [])]; + // Filter out self-mentions (owner's own replies appearing as webmentions) + function isSelfMention(wm) { + if (!siteOrigin) return false; + var source = wm['wm-source'] || wm.url || ''; + return source.startsWith(siteOrigin); + } + // Build dedup sets from conversations items (richer metadata, take priority) const convUrls = new Set(convItems.map(c => c.url).filter(Boolean)); const seen = new Set(); @@ -162,6 +182,7 @@ // Add conversations items first (they have platform provenance) for (const wm of convItems) { + if (isSelfMention(wm)) continue; const key = wm['wm-id'] || wm.url; if (key && !seen.has(key)) { seen.add(key); @@ -177,8 +198,9 @@ if (authorUrl) authorActions.add(authorUrl + '::' + action); } - // Add webmention-io items, skipping duplicates + // Add webmention-io items, skipping duplicates and self-mentions for (const wm of wmItems) { + if (isSelfMention(wm)) continue; const key = wm['wm-id']; if (seen.has(key)) continue; // Also skip if same source URL exists in conversations