This post shows how to use the Webmention.io API to display all the interactions people have had with your blog posts.
You’ll need two things to make this work:
- Your website must be set up to use the Webmention.io service.
- You’ll need a bit of custom JavaScript to show the interactions below each blog post.
Setting up Webmention.io itself is outside the scope of this post, as this website already provides detailed instructions.
Now, let’s move on to the custom JavaScript you’ll need.
The JavaScript Code
Below is the complete JavaScript code. I’ll explain how each part works after the code.
if (document.querySelector("body").classList.contains("post")) {
function setContent(child) {
switch (child["wm-property"]) {
case "in-reply-to":
return child.content?.text;
case "like-of":
return "liked this";
case "repost-of":
return "reposted this";
default:
return "interacted with this post in an unknown way";
}
}
async function fetchInteractions(headerTitle) {
const response = await fetch("https://webmention.io/api/mentions.jf2?target=" + document.URL);
const data = await response.json();
if (data && data.children.length > 0) {
const interactions = document.createElement("div");
interactions.innerHTML = `<h3>${headerTitle ?? "Interactions"}</h3>`;
for (const child of data.children) {
const interaction = document.createElement("div");
interaction.innerHTML = `
<p>
<strong><a href="${child.author.url}" target="_blank">${child.author.name}</a></strong>
<small> - ${new Date(child["wm-received"]).toLocaleString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
})}</small>
</p>
<blockquote>${setContent(child)}</blockquote>
`;
interactions.appendChild(interaction);
}
const upvoteForm = document.getElementById("upvote-form");
upvoteForm.parentNode.insertBefore(interactions, upvoteForm.nextSibling);
}
}
fetchInteractions(document.currentScript.getAttribute("data-interactions"));
}
The main logic is in the fetchInteractions()
function, which accepts one parameter: the text to display as the header for all interactions. By default, the header text is "Interactions," but you can customize it by setting a data-interactions
attribute on the <script>
tag.
At the top, there’s an if
statement specific to Bear blog that ensures this code only runs on pages containing blog posts.
The fetchInteractions()
function retrieves interactions specific to the current page using document.URL
. The Webmention API endpoint used here is documented on the Webmention.io homepage.
A new div
element is created (stored in the variable interactions
) to hold all the interactions. For each child
element in the retrieved data, a separate div
is created with the details of a single interaction (stored in the variable interaction
). This child
data populates an HTML template displaying the author, date, and content of each interaction.
The setContent()
function helps format the content based on the interaction type. It currently supports three types: replies (with text), likes, and reposts, each showing different text depending on the type.
Finally, in the fetchInteractions()
function, the interactions element is inserted just below the upvote-form
element, which is also specific to Bear blog.
And that's it! With this setup, you can easily show interactions on your blog posts. Happy blogging!