Web::Mention - Implementation of the IndieWeb Webmention protocol


 use Web::Mention;
 use Try::Tiny;
 use v5.10;

 # Building a webmention from an incoming web request:

 my $wm;
 try {
 catch {

     my $source = $wm->original_source;
     my $target = $wm->target;
     my $author = $wm->author;

     my $name;
     if ( $author ) {
         $name = $author->name;
     else {
         $name = $wm->source->host;

     if ( $wm->is_like ) {
         say "Hooray, $name likes $target!";
     elsif ( $wm->is_repost ) {
     elsif ( $wm->is_reply ) {
         say $wm->content;
     else {
 else {
    say "This webmention doesn't actually mention its target URL, "
        . "so it is not verified.";

 # Manually buidling and sending a webmention:

 $wm = Web::Mention->new(
    source => $url_of_the_thing_that_got_mentioned,
    target => $url_of_the_thing_that_did_the_mentioning,

 my $success = $wm->send;
 if ( $success ) {
     say "Webmention sent successfully!";
 else {
     say "The webmention wasn't sent successfully.";
     say "Here's the response we got back..."
     say $wm->response->as_string;


 my @wms = Web::Mention->new_from_html(
    source => $url_of_a_web_page_i_just_published,
    html   => $relevant_html_content_of_that_web_page,

 for my $wm ( @wms ) {
    my $success = $wm->send;


This class implements the Webmention protocol, as defined by the W3C and the IndieWeb community. (See This article by Chris Aldrich for an excellent high-level summary of Webmention and its applications.)




Class Methods


 $wm = Web::Mention->new(
    source => $source_url,
    target => $target_url,

Basic constructor. The source and target URLs are both required arguments. Either one can either be a URI object, or a valid URL string.

Per the Webmention protocol, the source URL represents the location of the document that made the mention described here, and target describes the location of the document that got mentioned. The two arguments cannot refer to the same URL (disregarding the #fragment part of either, if present).


 @wms = Web::Mention->new_from_html(
    source => $source_url,
    html   => $html,

Convenience batch-construtor that returns a (possibly empty) list of Web::Mention objects based on the single source URL (or URI object) that you pass in, as well as a string containing HTML from which we can extract zero or more target URLs. These extracted URLs include the href attribute value of every <a> tag in the provided HTML.

Note that (as with all this class's constructors) this method won't proceed to actually send the generated webmentions; that step remains yours to take. (See "send".)



Convenience constructor that looks into the given web-request object for source and target parameters, and attempts to build a new Web::Mention object out of them.

The object must provide a param( $param_name ) method that returns the value of the named HTTP parameter. So it could be a Catalyst::Request object or a Mojo::Message::Request object, for example.



 use JSON;

 $wm = Web::Mention->FROM_JSON(
    JSON::decode_json( $serialized_webmention )

Converts an unblessed hash reference resulting from an earlier serialization (via JSON) into a fully fledged Web::Mention object. See "SERIALIZATION".

The all-caps spelling comes from a perhaps-misguided attempt to pair well with the TO_JSON method that JSON requires. As such, this method may end up deprecated in favor of a less convoluted approach in future releases of this module.


 Web::Mention->content_truncation_marker( $new_truncation_marker )

The text that the content method will append to text that it has truncated, if it did truncate it. (See "content".)

Defaults to ....


 Web::Mention->max_content_length( $new_max_length )

Gets or sets the maximum length, in characters, of the content displayed by that object method prior to truncation. (See "content".)

Defaults to 200.

Object Methods


 $author = $wm->author;



 $content = $wm->content;

Returns a string containing this object's best determination of this webmention's display-ready content, based on a number of factors.

If the source document uses Microformats2 metadata and contains an h-entry MF2 item, then returned content may come from a variety of its constituent properties, according to the IndieWeb comment-display algorithm.


In any case, the string will get truncated if it's too long. See "max_content_length" and "content_truncation_marker".


 my $uri = $wm->endpoint;

Attempts to determine the webmention endpoint URL of this webmention's target. On success, returns a URI object. On failure, returns undef.



 $bool = $wm->is_tested;

Returns 1 if this object's verify() method has been called at least once, regardless of the results of that call. Returns 0 otherwise.


 $bool = $wm->is_verified;




 $original_url = $wm->original_source;


(It makes this determination based on the possible presence a u-url property in an h-entry found within the source document.)


 my $response = $wm->response;

Returns the HTTP::Response object representing the response received by this webmention instance during its most recent attempt to send itself.

Returns undef if this webmention instance hasn't tried to send itself.


 my $rsvp = $wm->rsvp_type;

If this webmention is of type rsvp (see "type", below), then this method returns the type of RSVP represented. It will be one of:

  • yes

  • no

  • maybe

  • interested

Otherwise, returns undef.


 my $bool = $wm->send;

Attempts to send an HTTP-request representation of this webmention to its target's designated webmention endpoint. This involves querying the target URL to discover said endpoint's URL (via the endpoint object method), and then sending the actual webmention request via HTTP to that endpoint.



 $source_url = $wm->source;

Returns the webmention's source URL, as a URI object.


 $html = $wm->source_html;



 $mf2_doc = $wm->source_mf2_document;

The Web::Microformats2::Document object that resulted from parsing the source document for Microformats2 metadata. If no such result, returns undef.


 $target_url = $wm->target;

Returns the webmention's target URL, as a URI object.


 $published_dt = $wm->time_published;

If the document fetched from the source URL explicitly declares a publication time via microformats, then this will return an appropriate DateTime object.

If not (or if the declared time seems to be invalid), then this will instead have the same return value as "time_received".

(It makes this determination based on the possible presence a dt-published property in an h-entry found within the source document.)


 $received_dt = $wm->time_received;

A DateTime object corresponding to this object's creation time.


 $verified_dt = $wm->time_verified;

If this webmention has been verified, then this will return a DateTime object corresponding to the time of verification. (Otherwise, returns undef.)


 my $title = $wm->title;

Returns a string containing this object's best determination of the display-ready title of this webmention's source document, considered separately from its content. (You can get its more complete content via the "content" method.

If the source document uses Microformats2 metadata and contains an h-entry MF2 item, and that item has a name property, then this method will return the text content of that name property.





 $type = $wm->type;

The type of webmention this is. One of:

  • mention (default)

  • reply

  • like

  • repost

  • quotation

  • rsvp

This list is based on the W3C Post Type Discovery document (, and adds a "quotation" type.


To serialize a Web::Mention object into JSON, enable the JSON module's "convert_blessed" feature, and then use one of that module's JSON-encoding functions on this object. This will result in a JSON string containing all the pertinent information about the webmention, including its verification status, any content and metadata fetched from the target, and so on.

To unserialize a Web::Mention object serialized in this way, first decode it into an unblessed hash reference via JSON, and then pass that as the single argument to the FROM_JSON class method.


This software is beta; its interface continues to develop and remains subject to change, but not without some effort at supporting its current API.

This library does not, at this time, support the proposed "Vouch" anti-spam extension for Webmention.


To file issues or submit pull requests, please see this module's repository on GitHub.



Jason McIntosh (


  • Mohammad S Anwar (



This is free software, licensed under:

  The MIT (X11) License




