🍿 5 min. read

Getting Started With Webmention and NextJS

Monica Powell

This past week I had the pleasure of being on the Learn with Jason Show to show how to add Webmention functionality to a NextJS website. Webmentions let you pull tweets, other blogs, and other activity from around the web into your site? It was fun live pair programming the implementation of webmentions. Check out the video or read some of the highlights below!

Watch the Learn with Jason Episode

Watch the Learn with Jason episode below for more information about Webmentions and view the transcript at https://www.learnwithjason.dev/webmention-next-js:

What are Webmentions?

Webmention are an IndieWeb specification to allow websites to collect comments from across the decentralized social web (i.e., Twitter, GitHub, Pinterest, Reddit) in a centralized place. A site can be set up to send an outgoing Webmention any time they link to an external website. Websites that receive Webmentions can then decide what content to display and bring the conversation to one place. I've mostly used Webmention to bring conversation from Twitter to my personal site.

Below is an image of how Webmentions appear on one my articles on this site:

scrolling through Webmentions which show the number of RTs, likes and replies. Toggled on and off the view that shows the content of individual replies

Setting up Webmention Functionality

The easiest way to set up your site to start receiving Webmentions is to create an account with webmention.io to accept Webmentions on your behalf. If you'd like to bring in conversation from social media sites like Twitter, I'd recommend creating an account with bridgy which will automatically poll social media at set intervals and send any relevant content as a Webmention to webmention.io. Let's walkthrough how to set up the necessary accounts:

  1. Begin receiving Webmentions with webmention.io Go to https://webmention.io/ and enter your website URL. It will prompt you to set up IndieAuth which requires you link to a social media site like Twitter on the homepage of your website with the HTML rel attribute value set to "me".

    1<a href="https://twitter.com/waterproofheart" rel="me"> Twitter</a>

    This set up is required so that webmention.io can verify that the social media website you use to log in is actually associated with the website you want them to collect Webmentions for.

    Once you've successfully set up your account you should see the following markup on webmention.io (with your username) under settings:

    1<link rel="webmention" href="https://webmention.io/username/webmention" />
    2<link rel="pingback" href="https://webmention.io/username/xmlrpc" />

    This markup should be added to the head of your website and deployed so that Webmentions will officially begin being collected by www.webmention.io.

    The above set up allows sites to start sending Webmentions to your site and allows you to be able to start sending Webmentions manually.

  2. Set up Brid.gy to automatically receive mentions from Twitter and other social media websites Social media websites like Twitter generally don't automatically send Webmention notifications to site despite a lot of link sharing occuring on the site. Therefore, in order to automatically send mentions of your website on Twitter to your site as a Webmention you need to setup Brid.gy. Brid.gy requires that you authenticate with a social media acocunt and also have a link back to the same domain in your social media profile's bio section.

Fetching and Rendering Webmentions

1. Fetch Webmentions

We used useEffect to make a fetch request from webmention.io to retrieve the Webmentions associated with our site and stored its result in state as mentions. The endpoint that the request is made to is https://webmention.io/api/mentions.jf2?[webmentioniousername]&token=[webmentioniotoken]. This URL should be updated with your webmentionio username and webmentionio token. Note the token only provides read-only access you can choose to keep the token a secret but re-generate as needed.

Since useEffect only triggers after the initial hydration of a React site, this request only occurs on the client-side and requires JavaScript to be enabled in order to fetch Webmention data. This means that you don't have to worry about rebuilding your site in order to retrieve the latest Webmention data.

1const [mentions, setMentions] = useState([]);
2 useEffect(() => {
4 fetch(
5 'https://webmention.io/api/mentions.jf2?[webmentioniousername]&token=[webmentioniotoken]'
6 )
7 .then((response) => response.json())
8 .then((result) => {
9 setMentions(result.children);
10 });
11 }, []);

If you are curious what the shape of the initial object returned by the endpoint looks like some recent Webmentions I received were shaped like:

2 "type": "feed",
3 "name": "Webmentions",
4 "children": [
5 {
6 "type": "entry",
7 "author": {
8 "type": "card",
9 "name": "Debra-Kaye Elliott",
10 "photo": "https://webmention.io/avatar/pbs.twimg.com/ca78346285aa621eedce7fa271025576c97a19577b4820c9951853d09a829ad8.png",
11 "url": "https://twitter.com/debrakayelliott"
12 },
13 "url": "https://twitter.com/waterproofheart/status/1312230169491447815#favorited-by-261719963",
14 "published": null,
15 "wm-received": "2020-10-03T17:29:46Z",
16 "wm-id": 864384,
17 "wm-source": "https://brid-gy.appspot.com/like/twitter/waterproofheart/1312230169491447815/261719963",
18 "wm-target": "https://www.aboutmonica.com/blog/set-yourself-up-for-success-open-source-contributions/",
19 "like-of": "https://www.aboutmonica.com/blog/set-yourself-up-for-success-open-source-contributions/",
20 "wm-property": "like-of",
21 "wm-private": false
22 },
23 {
24 "type": "entry",
25 "author": {
26 "type": "card",
27 "name": "Anders Schneiderman",
28 "photo": "https://webmention.io/avatar/pbs.twimg.com/37890c358e8ff1f667c57d89959e583af37ef66d39b6d3c372d9b7988f5a377f.jpg",
29 "url": "https://twitter.com/raschneiderman"
30 },
31 "url": "https://twitter.com/waterproofheart/status/1312230169491447815#favorited-by-270006742",
32 "published": null,
33 "wm-received": "2020-10-03T15:08:41Z",
34 "wm-id": 864330,
35 "wm-source": "https://brid-gy.appspot.com/like/twitter/waterproofheart/1312230169491447815/270006742",
36 "wm-target": "https://www.aboutmonica.com/blog/set-yourself-up-for-success-open-source-contributions/",
37 "like-of": "https://www.aboutmonica.com/blog/set-yourself-up-for-success-open-source-contributions/",
38 "wm-property": "like-of",
39 "wm-private": false
40 },
41 ]}

You can also view the shape of the data by going directly to https://webmention.io/api/mentions.jf2?[webmentioniousername]&token=[webmentioniotoken].

2. Render Webmentions

Once we have the mentions stored in state from the request to webmention.io we can map through the mentions and render the a link to the Webmention author's original post, their photo, name and the content of their Webmention.

1{mentions.map((mention) => (
2 <div>
3 <a href={mention.author.url}>
4 <img
5 style={{ width: 100 }}
6 src={mention.author.photo}
7 alt={mention.author.name}
8 />
9 </a>
10 <div dangerouslySetInnerHTML={{ __html: mention.content.html }} />
11 </div>
12 ))}

Final Code

Below is more complete version of the above code with some styling. Check out the demo repo for the application I created with Jason on Learn with Jason here: https://github.com/jlengstorf/next-netlify-webmention

1import { useEffect, useState } from 'react';
3 const Index = ({...props }) => {
4 const [mentions, setMentions] = useState([]);
5 useEffect(() => {
6 /* add your webmentionio username and webmentionio token.
7 Note the token only provides read-only access
8 you can choose to keep the token a secret but re-generate as needed */
9 fetch(
10 'https://webmention.io/api/mentions.jf2?[webmentioniousername]&token=[webmentioniotoken]'
11 )
12 .then((response) => response.json())
13 .then((result) => {
14 setMentions(result.children);
15 });
16 }, []);
17 return (
18 <>
19 <Layout>
20 <h2>Discussion about this site on the web</h2>
21 <p>This uses Webmention</p>
22 {mentions.map((mention) => (
23 <div
24 style={{
25 display: 'grid',
26 gap: '1rem',
27 gridTemplateColumns: '100px 1fr',
28 }}
29 >
30 <a href={mention.author.url}>
31 <img
32 style={{ width: 100 }}
33 src={mention.author.photo}
34 alt={mention.author.name}
35 />
36 </a>
37 <div dangerouslySetInnerHTML={{ __html: mention.content.html }} />
38 </div>
39 ))}
40 </Layout>
41 <style jsx>{`
42 .title {
43 margin: 1rem auto;
44 font-size: 3rem;
45 }
46 `}</style>
47 </>
48 );
49 };
51 export default Index;

This article was published on October 03, 2020.

Don't be a stranger! 👋🏾

Thanks for reading "Getting Started With Webmention and NextJS". Join my mailing list to be the first to receive my newest web development content, my thoughts on the web and learn about exclusive opportunities.


    I won’t send you spam. Unsubscribe at any time.


    • Grant Hutchins
    • shanice.sh
    • Luis Chilo
    • MonkeyGirlGamer21
    • Jennifer Ponder
    • Matthias Zepper
    • Learn With Jason
    • Aadesh
    • Yenly
    • clairy💛
    • Israel Zurita
    • :party-corgi:
    • C://gilbertsosi/v3.0
    • Mike Aparicio
    • Joe Previte
    • Heru Gunawan
    • Not Martin Grubinger
    • Prabin Poudel
    • Robin Cussol
    • Maxence Poutord @ 🇩🇪
    • Josh Finnie
    • Dwayne
    • SpoOoOoOopy Jason 💀🦇
    • MOVI🌼
    • euni
    • Charletta Bullard
    • Vedurumudi Priyanka
    • Rich Haines
    • IvaKop
    • Gift Egwuenu
    • Dave Garwacke
    • Nika Zawila