10 ms·
Adding comments to a static blog with Mastodon
- CarelessExpert 6y agoI achieve this using https://brid.gy/ https://brid.gy/ (or https://fed.brid.gy/ https://fed.brid.gy/ if you want your blog to appear as a first class member of the Fediverse), though in my case I just syndicate out to Twitter. I then collect the webmentions using https://webmention.io/ https://webmention.io/. The nice thing about this is I get a breadth of methods for receiving comments/reactions across multiple platforms, including anything that directly supports webmention (such as https://micro.blog/ https://micro.blog/, where my posts are also syndicated), without having to do any of the platform-specific wiring myself.
- ognarb 6y agoI keep hearing about webmentions in my fediverse bubble, maybe one day I should take a look at it.
- CarelessExpert 6y agoHonestly, I set up webmentions to use brid.gy, not just for the sake of using webmentions. I wanted a two-way integration between my static blog and Twitter, and this solution has done the job nicely. That I ended up with direct webmention support was just a bonus as far as I'm concerned.
- FalconSensei 6y agoSo, would brid.gy automatically post your blog post to twitter? That's what you mean by two-way integration?
- CarelessExpert 6y agoCorrect. Using the right microformats, it'll auto syndicate notes as tweets and full posts as tweets with a summary and a link. All my site has to do is shoot out a webmention to brid.gy and it does the rest. Then when people react (reply, like, etc) it'll proxy those interactions back as webmentions.
- input_sh 6y agoFor the unaware, they're essentially identical to WordPress' Pingbacks. You configure your website so that other websites let you know whenever they link to you.
- andrewshadura 6y agoGreat, thanks! I was just about to write something similar, and now I think I don't need to
- StavrosK 6y agoThis looks fantastic, does it support plain RSS? My blog is a static site, but I'd like it to be exposed to the fediverse.
- CarelessExpert 6y agoJust check the site for details. The short version is you need an Atom feed.
- StavrosK 6y agoI did, looks like it needs webmentions, which needs server-side code.
- CarelessExpert 6y agoThat's what webmention.io is for. It'll receive webmentions on your behalf and then expose an API to pull em down. You hit that API during your static site build or do it dynamically with some client side JS. Either way it allows you to avoid hosting any services yourself.
- StavrosK 6y agoOh I see, thank you.
- winrid 6y ago(another) self plug - if you use FastComments, you can get an RSS feed of your comments: https://blog.fastcomments.com/(7-08-2020)-create-an-rss-feed-from-your-comments.html https://blog.fastcomments.com/(7-08-2020)-create-an-rss-feed...
- rattray 6y agoNice! How much does this approach cost (ballpark)?
- CarelessExpert 6y agoOther than my time to set it up? Zero. All the services I mentioned are operated for free (or can be self-hosted).
- criddell 6y agoAre the interactions valuable enough that if it weren’t available for free, you would be willing to pay for it each month?
- CarelessExpert 6y agoI'm not doing anything to build a readership, so my content doesn't get a lot of interactions. So for me, no. If I had a real twitter following, though, I might have a different answer.
- FalconSensei 6y agoThanks a lot for the tip. Did that last night and it was very easy to set up. Now I just need to display them on my blog :)
- progval 6y agodocument.getElementById('mastodon-comments-list').innerHTML = data['descendants'].reduce(function(prev, reply) { mastodonComment = ` ... `; return prev + DOMPurify.sanitize(mastodonComment); }, ''); Why is it implemented like this? It looks quadratic, while it's trivial (and more intuitive IMO) to make it linear: document.getElementById('mastodon-comments-list').innerHTML = data['descendants'].map(function(reply) { return DOMPurify.sanitize(` ... `); }).join('');
- brabel 6y agoYour alternative is also pretty bad as it will generate lots of intermediate Strings before joining them up... Just use a forEach instead and append directly to the DOM: let root = document.getElementById('mastodon-comments-list'); data['descendants'].forEach(reply => { let div = document.createElement('div'); div.innerHtml = DOMPurify.sanitize( ... ); root.append(div); });
- jlokier 6y ago"Pretty bad" is unwarranted in my opinion. Your alternative adds overhead of creating an extra div for each intermediate string in the code it replaces. It's trivial overhead, and may be a small number, but exactly the same applies to the overhead of temporary strings - they are comparable. Intermediate string length doesn't matter for time complexity here. If they are short they will be fast. If they are long, the time to scan and parse in DOMPurify and innerHTML will dominate. After building the DOM, your extra divs are processed every time that section of the DOM is styled and rendered, not just once. If the number of extra divs is low enough that this is negligible, so is the number of intermediate strings in the alternative code. So I wouldn't assume your version is faster at setting up, and it may be marginally slower later on repeated renderings. I'd profile both versions, maybe with Browserscope (which probably has a test for this particular question already). However if I couldn't profile and was asked my guess at the fastest version, my guess is the string-join version. I'd be more concerned with whether concatenating DOMPurify.sanitize() strings is guaranteed to maintain the same security properties.
- unicornporn 6y agoHow about https://webmention.io/ https://webmention.io/ ? Fediverse-friendly and Twitter-friendly.
- FalconSensei 6y agoseems like a cool idea, but without any demo to try, it's hard to go for it
- unicornporn 6y agoIt's implemented here: https://www.kickscondor.com/meat-computer https://www.kickscondor.com/meat-computer
- floatingatoll 6y agoDoes syndicating third-party content onto your blog in this way expose you to legal liability for publishing that content? Are deletions and takedowns synced back from Mastodon, such as when someone is taken offline for breaking local law with their Mastodon instance, or would their content remain published on your blog?
- ognarb 6y agoI can technically filter comments pretty easily from the js script. When a comment is removed from mastodon it is also removed from the blog.
- FalconSensei 6y agoWhat I do with Hugo is: - Added reddit and twitter attributes on the frontmatter - After publishing and sharing to both services, I paste reddit link/tweet id to the frontmatter and rebuild - On the blogs footer, I just embed both posts, so people can see how many replies, and also click to be redirected reply on each respective service. Although I would love something more automated (and preferably with in-site response), at least this is a good flow for the readers.
- mstibbard 6y agoThis seems like a good approach (acknowledging it limits you to only comments from reddit/twitter users). How do you embed the posts so it shows # of replies?
- FalconSensei 6y ago> acknowledging it limits you to only comments from reddit/twitter users As of now, my only visitors are a few anime bloggers from my circle, all of them using WordPress. As it's not possible to use WordPress comments, I'm not losing anything besides that. I could use Disqus, but I hate it, and I think they would log-in with Twitter to leave a Disqus comment so... As for embedding, I use Hugo's Twitter shortcode, and reddit standard embed code - as all embed are from my own subreddit, I left that hardcoded, with a placeholder title, and just change the url on the code. Seems that Twitter embed changed recently to not show number of replies anymore, but that's alright for now. They have to click on the embedded tweet and go to twitter to reply anyway :/ I might add the webmentions thing mentioned in other comments here to show the actual replies. This is how it looks right now: https://geekosaur.com/post/anime-controversies-controversed/ https://geekosaur.com/post/anime-controversies-controversed/
- FalconSensei 6y agoI have absolutely no idea why was that downvoted. Anyone care to explain?
- chrismorgan 6y agoThe technique demonstrated here for producing the markup is bad: 1. The use of DOMPurify is either unnecessary or insufficient. Specifically consider reply.content, which is provided from the server as HTML. (I believe it’s the only one that’s supposed to be serialised HTML; all the other fields are text.) If the backend guarantees that you get a clean DOM, DOMPurify is unnecessary†. But if it’s possible for a user to control the markup in that field completely, then DOMPurify as configured is insufficient, because although it blocks XSS and JavaScript execution, it doesn’t filter out remote resource loading and CSS, which can be almost as harmful. Trivial example, <a href=//malicious.example style=position:fixed;inset:0>pwned</a>. Given the type of content, you probably want to either blacklist quite a few things (e.g. the style attribute, and the img, picture, source, audio and video tags), or whitelist a small set of things. 2. Various fields that could hypothetically contain magic characters are dropped in with no escaping. If they do contain magic characters like < and &, you’ve just messed up the display and opened the way for malicious resource loading and problem № 3 below. Even if they are supposed to be unable to contain a magic character (e.g. I’m going to guess that reply.account.username is safe), it’s probably a good idea to escape them anyway just in case (perhaps an API change later makes it possible), and to guard against errant copy–pasters and editors of the code that don’t know what they’re doing. Perhaps at some point you’ll add or switch to reply.account.display_name, which probably can contain < and &. 3. The markup is produced by mixing static templating with user-provided input, and sanitisation is performed on the whole thing. It’s important when doing this sort of templating that each user-provided input be escaped or sanitised by itself in isolation, not as part of a whole that has been concatenated. Otherwise you can mess with the DOM tree accidentally or deliberately. Suppose, for example, that reply.content could contain `</div></div></div><img src=//ad.example alt="Legitimate-looking in-stream ad"><div class="mastodon-comment">…<div class="content">…<div class="mastodon-comment-content">…`. So this means: • Apply attributes and text nodes to a real DOM (e.g. `img = new Image(); img.src = reply.account.avatar_static; avatar.append(img)`), or escape them in the HTML serialisation (e.g. `<img src="${reply.account.avatar_static.replace(/&/g, "&").replace(/"/g, """)}">`). • Do HTML sanitisation on just the user input, e.g. DOMPurify.sanitize(reply.content). A part of my problem with the code as written is that, purely from looking at the code, I can see that there may well be various security holes. I require knowledge of the backend also before I can judge whether there are security holes. Where possible, it’s best to write the code in such a way that you know that it’s safe, or that it’s not—try not to depend on subtle things like “the particular fields that we access happen to be unable to contain angle brackets, ampersands and quotes”, because they’re fragile. Incidentally, it would also be more efficient to run DOMPurify with the RETURN_DOM_FRAGMENT option, and append that, rather than concatenating it to a string and setting innerHTML. Saves a pointless serialisation/deserialisation round trip, and avoids any possibility of new mXSS vulnerabilities that might be discovered in the future. (I don’t really understand why DOMPurify defaults to emitting a string. I can’t remember seeing a single non-demo use of DOMPurify where the string is preferable to a DOM fragment.) — † Though if the server sanitised arbitrary user-provided HTML/MathML/SVG, I probably don’t trust it as much as I trust DOMPurify, for things that end up in the DOM. There are some pretty crazy subtleties in things like HTML serialisation round-tripping of HTML, SVG and MathML content. There’s fun reading in the changelogs and security patches.
- kordlessagain 6y agoI use Github Pages for my blog and just found this little gem for implementing comments using issues: https://danyow.net/using-github-issues-for-blog-comments/ https://danyow.net/using-github-issues-for-blog-comments/
- modeless 6y agoInteresting. GitHub recently added a "discussions" feature. I wonder if it would be more suitable for this use.
- strenholme 6y agoI switched over from a hacked together bbPress site for MaraDNS support to using GitHub discussions (which I also link to for blog comments). It’s one less site for me to maintain.
- deleted 6y ago[deleted]
- schwartzworld 6y agoThis is the strategy I'm using for https://Schwartz.world/blog https://Schwartz.world/blog It makes sense for a coding blog since you can assume most of your users have a GitHub account.
- dmje 6y agoAll looked great until this: "You can use your Mastodon account to reply to this post" and then you lost 99% of your possible commenters
- pingiun 6y agoThis seems like a feature to me
- morlockabove 6y agoKeeping your commenter-base small and elitist seems like a good thing. That's the point of moderation, right?
- llbeansandrice 6y agoDo people like comments on blogs? I can't find the links right now but I've found a couple of people talking about how they used to have comments on their blog and decided to get rid of it since they would occasionally become a curation/moderation nightmare.
- input_sh 6y agoPersonally, no. They distract me from content and I often find myself jumping to comments directly if I know there are some. I'm from a region where they're pretty common on news sites, so I've created a Firefox add-on that hides the comments from about 40 local websites that I chose via Alexa ranks.
- INTPenis 6y agoDepends on the content but in good cases comments add crowd sourced fact checking to blogs. That's why I love reading HN comments on hot topic articles.
- llbeansandrice 6y agoI guess I go to different places for that. The blog itself doesn't feel like a discussion platform to me like HN, reddit, etc. Those platforms have systems, rules, moderators, etc. for dealing with more free-form discussions. I personally never read comments on blogs and I find having a "Contact Me" link at the bottom is better. On my blog I use a gmail account and a template for new articles so I get `[Contact Me](emailto:my.email+shorttitle@gmail.com)` so they're easy to categorize.
- INTPenis 6y agoSure but not all blogs are posted on HN. But yeah these days you could technically have a reddit thread on your user page for each of your blog posts. But how is that different than mastodon? At least you can self-host mastodon.
- failrate 6y ago"One of the biggest disadvantages of static site generators is that they are static and can’t include comments." At first, I misread this as "One of the biggest advantages...", and I still think that is the correct conclusion.
- ognarb 6y agoI guess it depends if you want to interact with your readers.
- failrate 6y agoI once made the mistake of putting an unguarded comment section on my now defunct blog. Within days, it was stuffed to the gills with tentacle porn links. There were no readers, just spam. I dropped the comments table and never went back.
- cutemonster 6y agoIf you leave the door to where you live wide open when you're away for some days, that can also end badly.
- failrate 6y agoYes, it was exactly that irresponsible.
- asim 6y agoYou can embed a comments API using micro - m3o.com. Sign-up, run the comments service, copy/paste some JS code and there you have it.
- deleted 6y ago[deleted]
- zlynx 6y agoOr your static page could have a link to a comments page. Which is also static. It is pretty trivial to generate a new static page which includes the new comment. You do want some kind of database. A SQLite file works fine.
- darekkay 6y agoI've gathered some more alternatives for static site comments on my blog [1] (ironically, I didn't include comments on my own blog) [1] https://darekkay.com/blog/static-site-comments/ https://darekkay.com/blog/static-site-comments/
- winrid 6y agoSelf plug. I run https://fastcomments.com https://fastcomments.com, which would also solve this problem, for example: https://blog.fastcomments.com/(6-26-2020)-embedding-comments-on-github-pages.html https://blog.fastcomments.com/(6-26-2020)-embedding-comments...
- ggggtez 6y ago> manually escaping every field. > Some fields don't look escaped. hmm So the future of social media is everyone becoming software engineers huh. Good luck with those toots.
- znpy 6y agoIs it my impression or it's basically impossible to do comment moderation by using Mastodon in this way? Or at least harder than it should be. I'd be happy to be proven wrong btw. EDIT: don't get me wrong, this is cool :)
- avery42 6y agoIf you point the comments to be fetched from an instance you host, I assume you could silence/suspend users or domains on your instance and they would no longer show up in the comments (although that's probably not an ideal solution for most cases).
- 40four 6y agoAs avery42 already mentioned, this is intended to be used on your own self hosted mastodon server. I have used my own off and on, and for admins, it actually has pretty powerful moderation tools. So the author is proposing tooting a link to the blog post article, and the leveraging your server’s REST endpoints to retrieve the comments. This actually seems quite powerful, and elegant to me. If you run your own server, this could be a very nice & simple solution.
- ognarb 6y agoYeah, fortunately for the moment I didn't receive any comments that I needed to remove. If you self host your mastodon server, it should be easy to remove comments but if you don't you basically have two choices: Report them and hope your admin remove them or filter them out with the small js script.
- _peeley 6y agoMinor (and probably not intentional) thing I like - comments are loaded manually rather than by default on page load. For more popular blogs/sites that have comments on posts like Slate Star Codex or Less Wrong, there can be literally hundreds or thousands of comments on a single post. This makes scrolling through the post or judging the amount of content in the post via scroll bar basically impossible, but just loading comments with a button click fixes that in such a simple way.
- ognarb 6y agoHiding the comments under a button was mostly because I wanted to limit to the maximum the number of request going to the mastodon server. But this has also the nice side effect of only loading them, if you need them.
- ric2b 6y agoIt does take quite a while to load though, is there a way to improve it, maybe with some caching on the server since the query is static?
- rajasimon 6y agoI'm building a very simple solution for this. Checkout https://blogstreak.com https://blogstreak.com and I got recently featured on betalist.
- ognarb 6y agoThe idea behind using Mastodon was to explicitly don't depends on another close source project and not depends on another silo. Your solution looks like it will be closed source and a silo.
- zdunn 6y agoI like the use of the fediverse for adding comments to a blog, but this is another example of conflating mastodon with the fediverse. I'm glad OP found a solution that works for them, but I hope too many people don't start using this technique. A user could comment using any fediverse account, including Pleroma, Friendica, PixelFed, etc. Summing that up with 'mastodon account' is damaging to the whole idea of the fediverse. Non-technical people might not realize that they can choose to use the other platforms. Also, I hate that the mastodon API has become the de facto standard for interacting with any fediverse platform. The other platforms implemented the API to maintain compatibility with mastodon clients. Now this not-quite-standard API is controlled by a single person who doesn't care about compatibility with other platforms.