Implementing Webmentions: A Practical Guide
A hands-on guide to implementing Webmentions on your website, including code examples and best practices.
Implementing Webmentions on your site might seem daunting at first, but the process is straightforward once you understand the core concepts.
Architecture Overview
A complete Webmention implementation consists of three main components:
| Component | Purpose | Complexity |
|---|---|---|
| Receiver | Accept incoming mentions | Low |
| Verifier | Validate mention authenticity | Medium |
| Sender | Send mentions to other sites | Low |
Setting Up a Receiver
The receiver is an HTTP endpoint that accepts POST requests. Here's a minimal example:
app.post('/webmention', async (req, res) => {
const { source, target } = req.body;
// Basic validation
if (!source || !target) {
return res.status(400).send('Missing source or target');
}
// Queue for verification
await queue.add('verify-webmention', { source, target });
res.status(202).send('Accepted');
});
Discovery
For sites to find your Webmention endpoint, you need to advertise it. Add this to your HTML <head>:
<link rel="webmention" href="https://your-site.com/webmention" />
Alternatively, you can use an HTTP header:
Link: <https://your-site.com/webmention>; rel="webmention"
Verification Process
Verification is crucial to prevent abuse:
- Fetch the source URL
- Parse the HTML content
- Check if the target URL exists in the source
- Extract relevant metadata (author, content, etc.)
Here's a simplified verification function:
async function verifyWebmention(source, target) {
const response = await fetch(source);
const html = await response.text();
// Check if target appears in source
if (!html.includes(target)) {
throw new Error('Target not found in source');
}
// Parse microformats for rich data
const mf2 = microformats.get({ html });
return {
verified: true,
author: extractAuthor(mf2),
content: extractContent(mf2)
};
}
Sending Webmentions
When you publish content with links, send Webmentions to notify the linked sites:
async function sendWebmention(source, target) {
// Discover the endpoint
const endpoint = await discoverEndpoint(target);
if (!endpoint) {
console.log('No Webmention endpoint found');
return;
}
// Send the mention
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ source, target })
});
return response.status === 202;
}
Security Considerations
Important: Always validate and sanitize content from external sources to prevent XSS attacks and spam.
Implement rate limiting and consider:
- Requiring moderation before displaying mentions
- Blocking known spam domains
- Checking for legitimate backlinks
- Using allowlists for trusted sources
Testing Your Implementation
Use these resources to test:
- Webmentions.com - Our hosted service for sending, receiving, and testing
- webmention.rocks - Test suite for spec compliance
- Telegraph - Alternative manual sending tool
Conclusion
With these building blocks, you can create a robust Webmention implementation that enables rich, decentralized interactions on your site. Start simple and iterate based on your needs.
Related Posts
Introduction to Webmentions
Learn what Webmentions are and how they enable decentralized conversations across the web.