Embedding Mastodon Feeds
The column on the left contains recent toots from two mastodon accounts while the column on the right contains recent toots with some hashtag. This is implemented by a web component using Mastodon's REST API.
The <mastodon-toots>
component takes a single
attribute url
for retrieving the toots.
You can use any URL of the mastodon API that provides a JSON array of
"statuses"
(= posts = toots).
See the mastodon API docs on retrieving
timelines
and
statuses.
For example:
-
https://mastodon.social/api/v1/accounts/13179/statuses?limit=10&exclude_replies=true
retrieves up to 10 recent toots from@Mastodon@mastodon.social
which are not replies, but which may be boosts. (Notice that the numeric account id of that user is 13179.)
Required parameters:- The mastodon instance goes to the host part of the URL.
- The numeric account id goes to the URL path.
-
limit
gives a maximum number of toots to be retrieved. -
exclude_replies
andexclude_reblogs
are boolean parameters. When set totrue
, replies or boosts are excluded from the toot list.
-
https://mastodon.social/api/v1/timelines/tag/cats?only_media=true&limit=10
retrieves up to 10 recent toots with hashtag#cats
and with at least one media attachment frommastodon.social
. -
https://mastodon.social/api/v1/timelines/public
retrieves a server-defined number of recent toots frommastodon.social
.
Here is a quick&dirty tool for finding an account id.
Type the account's username and instance (separated by "@")
in the input field and press the Enter key.
The output of the component does not go to shadow DOM. So it can be styled with CSS for the main ("light") DOM tree.
The component only works if CORS is enabled by the server. All the mastodon servers I tried actually had this enabled.
Features that might be added:
- Smarter sanitizing of the HTML toot contents
- Support custom emojis also in the toot content
- Support more types of attached media
- Refine link previews ("cards"), e.g. for videos and server-provided HTML
- Regular or user-triggered updates for displaying new toots
- Internationalization/localization of error messages
- Load older toots on demand (or when the user has scrolled to the end)
- Support changes to the
url
attribute
Contributions and suggestions welcome! (To my mastodon account @hcschuetz@mastodon.social, in the discussion section of the github repo, or even as a pull request.)
I haven't npm-packaged the code (yet) because users of the component will probably want to tweak a few things here and there. I don't want to complicate the code by adding a lot of configurability. It should be easy for web developers to tweak their copy of the code directly. Furthermore such tweaks may depend on third-party code, but I'd like to avoid dependencies in the "vanilla" version.
Also notice that both the web component and the demo page run directly from the source code. There is no build step.
An Open Problem
When viewing the demo page
- in Firefox for Android
- on my Samsung tablet
- in landscape orientation,
scrolling the toot boxes does not work reliably. Scrolling does work if I replace Firefox with Chrome, or if I use Firefox on my Samsung/Android mobile, or if I simply rotate my tablet to portrait orientation.
Can anybody reproduce the problem? Is this a Firefox issue? Is there a known solution or work-around?
Similar Projects
There are various instructions and projects doing similar (but somewhat different) things. I am aware of these:
-
Mastodon embed timeline widget:
Seems to be more powerful than the code here, but also more heavy-weight. -
Emfed: Simple Client-Side Mastodon Feed Embedding:
Quite similar in scope to the project here. Comes as an npm package with a dependency on dompurify. -
Include Mastodon Feed:
A wordpress plugin with similar functionality. -
mastofeed:
A server-based approach. The server provides a document which can be embedded in a web page as an<iframe>
. (There's also the fork fedifeed with additional functionality.) -
Integration des Mastodon-Feeds in die eigene Webseite:
Instructions in German. More basic than the code here. But it also covers an RSS-based approach.
So you have to find your compromise between functionality and simplicity as well as between ready-made and easily adaptable code.