Often I want to know if a page supports webmentions, so I know if I should respond only from my website or directly on that page.
On a desktop browser I can inspect the response headers and page source for a webmention endpoint. But it’s a little bit of work and something I can't do at all on my phone. So I made this little bookmarklet:
Drag that to your bookmark bar, or if you’re on iOS, copy the below JavaScript, create a new bookmark (Share Icon > Add Bookmark), change the name to “Supports Webmentions?”, and paste the copied javascript as the URL address for the bookmark.
Here it is in a more readable format (also on Github):
javascript: (() => {
// Set some strings for the common result scenarios.
const support = "Page supports webmentions!";
const noSupport = "Page does not support webmentions :(";
// Create a dialog element and insert into the DOM.
let d = document.createElement('dialog');
document.getElementsByTagName('body')[0].appendChild(d);
// Remove the dialog element when it's closed.
d.addEventListener('close', () => {
d.remove();
});
// Create the contents of the dialog.
let content = document.createElement('p');
let close = document.createElement('form');
close.method = 'dialog';
close.innerHTML = "<button>Close</button>";
// Insert into the dialog element.
d.appendChild(content);
d.appendChild(close);
// Go ahead and set the initial status and show the dialog as a modal.
content.innerHTML = "Checking page source for <code>link[rel~=webmention]</code> or <code>a[rel~=webmention]</code>…";
d.showModal();
// The official spec (https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint) calls for
// checking for a Link HTTP header first, and then for these elements in the source. Since we don't care about
// finding the correct webmention endpoint, only if one exists, we can check source first and potentially save
// an HTTP request.
// Get all `link` and `a` elements that have a `rel` attribute containing "webmention".
let els = document.querySelectorAll('link[rel~=webmention], a[rel~=webmention]');
// If any of those elements exist, the page supports webmentions.
if (els.length > 0) {
content.innerHTML += '<br/>Page source contains <code>link[rel~=webmention]</code> or <code>a[rel~=webmention]</code>!<br/><br/>' + support;
return;
}
// If none exist, check the Link HTTP header.
content.innerHTML += '<br/>Page source does not contain <code>link[rel~=webmention]</code> or <code>a[rel~=webmention]</code>.<br/><br/>Checking page for Link HTTP header…';
// Make a HTTP request for the current page.
let location = window.location;
fetch(location).then((response) => {
// If the response does not have a Link header, then this page does not support webmentions.
if (!response.headers.has("Link")) {
content.innerHTML += '<br/>Page does not have a Link HTTP header.<br/><br/>' + noSupport;
return;
}
// The Link header can contain multiple values, separated by commas.
let links = response.headers.get("Link").split(",");
// If no links, then the Link header is empty and the page does not support webmentions.
if (links.length <= 0) {
content.innerHTML += '<br/>Link HTTP header is empty.<br/><br/>' + noSupport;
return;
}
// Iterate over the links, checking each one for a `rel=webmention` value. If one exists, then the page
// supports webmentions.
for (let link of links) {
if(/;\s*rel=["']?webmention["']?/.test(link)) {
content.innerHTML += '<br/>Page has a Link HTTP header with `rel="webmention"`.<br/><br/>' + support;
return;
}
}
// Otherwise the page does not support webmentions.
content.innerHTML += '<br/>Page does not have a Link HTTP header with `rel="webmention"`.<br/><br/>' + noSupport;
}).catch(e => {
// Output any errors from the Link header check to the dialog.
content.innerHTML += "<br/><br/>Error checking for Link header: " + e;
});
})();
I’m not completely happy with the HTTP header regex. While it will match rel=webmention
, rel="webmention"
, and rel='webmention'
, it won’t match rel
values with more than one space-delimited value, which I think is technically valid syntax.
I’ve tested it against the Webmention Rocks test suite, and it passed all of those scenarios.
P.S. This is a convenient tool for escaping the JavaScript for embedding a bookmarklet as the href
of an anchor
element.