Demo
1. Get your Mastodon ID
First you’ll need your Mastodon ID
https://example.social/api/v1/accounts/lookup?acct=your-username
In our case https://mastodon.cloud/api/v1/accounts/lookup?acct=blackspike returns the ID 109461933672061521
2. Fetch the posts
Then you’ll need to make a simple fetch call
const postsUrl = "https://mastodon.cloud/api/v1/accounts/109461933672061521/statuses"
const postsFetch = await fetch(postsUrl)
const posts = await fetchPosts.json()
That will return a JSON array like this
[
{
"id": "110299745197176137",
"created_at": "2023-05-02T15:15:45.611Z",
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"sensitive": false,
"spoiler_text": "",
"visibility": "public",
"language": "en",
"uri": "https://mastodon.cloud/users/blackspike/statuses/110299745197176137",
"url": "https://mastodon.cloud/@blackspike/110299745197176137",
"replies_count": 0,
"reblogs_count": 0,
"favourites_count": 0,
"edited_at": null,
"favourited": false,
"reblogged": false,
"muted": false,
"bookmarked": false,
"pinned": true,
"content": "\u003cp\u003eWe are delighted to push our new website live – we welcome shares \u0026amp; feedback 🖤\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.blackspike.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"\u003e\u003cspan class=\"invisible\"\u003ehttps://www.\u003c/span\u003e\u003cspan class=\"\"\u003eblackspike.com\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e\u003c/p\u003e",
"filtered": [],
"reblog": null,
"application": null,
"account": {
"id": "109461933672061521",
"username": "blackspike",
"acct": "blackspike",
"display_name": "blackspike design",
"locked": false,
"bot": false,
"discoverable": true,
"group": false,
"created_at": "2022-12-05T00:00:00.000Z",
"note": "\u003cp\u003eA freelance full-stack creative development team working remotely from Brighton, UK\u003c/p\u003e",
"url": "https://mastodon.cloud/@blackspike",
"avatar": "https://media.mastodon.cloud/accounts/avatars/109/461/933/672/061/521/original/eb1f3ebaecf23fce.png",
"avatar_static": "https://media.mastodon.cloud/accounts/avatars/109/461/933/672/061/521/original/eb1f3ebaecf23fce.png",
"header": "https://media.mastodon.cloud/accounts/headers/109/461/933/672/061/521/original/53e72b9acfdbc9e7.jpg",
"header_static": "https://media.mastodon.cloud/accounts/headers/109/461/933/672/061/521/original/53e72b9acfdbc9e7.jpg",
"followers_count": 5,
"following_count": 4,
"statuses_count": 16,
"last_status_at": "2023-05-02",
"noindex": false,
"emojis": [],
"roles": [],
"fields": [
{
"name": "www",
"value": "\u003ca href=\"https://blackspike.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"\"\u003eblackspike.com\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e",
"verified_at": "2023-04-13T12:30:23.994+00:00"
},
{
"name": "Twitter",
"value": "\u003ca href=\"https://twitter.com/blackspikeltd\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"\"\u003etwitter.com/blackspikeltd\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e",
"verified_at": null
},
{
"name": "new website coming soon!",
"value": "\u003ca href=\"https://beta.blackspike.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"\"\u003ebeta.blackspike.com\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e",
"verified_at": "2023-04-13T12:30:51.474+00:00"
}
]
},
"media_attachments": [
{
"id": "110299741526912479",
"type": "gifv",
"url": "https://media.mastodon.cloud/media_attachments/files/110/299/741/526/912/479/original/492f846154047751.mp4",
"preview_url": "https://media.mastodon.cloud/media_attachments/files/110/299/741/526/912/479/small/492f846154047751.png",
"remote_url": null,
"preview_remote_url": null,
"text_url": null,
"meta": {
"original": {
"width": 960,
"height": 960,
"frame_rate": "60/1",
"duration": 14.167,
"bitrate": 6587363
},
"small": {
"width": 400,
"height": 400,
"size": "400x400",
"aspect": 1.0
},
"focus": { "x": 0.0, "y": 0.0 }
},
"description": "a screen recording of the homepage of blackspike.com being scrolled",
"blurhash": "U58WaQpvI.$+{[EkNds+8zE0x]kDF-xct7Sc"
}
],
"mentions": [],
"tags": [],
"emojis": [],
"card": {
"url": "https://www.blackspike.com/",
"title": "blackspike design - creative web development",
"description": "blackspike design is a freelance full-stack creative development team working remotely from Brighton, UK",
"type": "link",
"author_name": "",
"author_url": "",
"provider_name": "",
"provider_url": "",
"html": "",
"width": 400,
"height": 210,
"image": "https://media.mastodon.cloud/cache/preview_cards/images/026/387/228/original/f69a0a79d5a5f7ec.jpg",
"embed_url": "",
"blurhash": "UGBeH^}Z=eA?[Ca0nOK3-BS#$is.=Lf,,?w^"
},
"poll": null
}
]
You can see in that example post there is a video and thumbnail image in the media_attachments
that we use in our demo carousel.
3. Create HTML from the returned JSON
Use a template literal to create the HTML list items and format the date with toLocaleDateString
const postsList = document.querySelector('.posts')
const postsUrl = 'https://mastodon.cloud/api/v1/accounts/109461933672061521/statuses'
const getPosts = async () => {
const fetchPosts = await fetch(postsUrl)
const posts = await fetchPosts.json()
const dateOptions = { year: 'numeric', month: 'long', day: 'numeric' }
const markup = posts.map(toot => `
<li class='toot'>
<div class='content'>${toot.content}</div>
<footer>
${new Date(toot.created_at).toLocaleDateString('en-GB', dateOptions)}
</footer>
</li>
`
)
.join('')
postsList.innerHTML = markup
}
getPosts()
Add a dash of CSS and you’re done
Of course you can add links, show images, play videos and hide replies etc, but it’s fantastic that you don’t have to worry about OAUTH or API keys or paying billionaires for the privilege of displaying your own content 🤌
See the Pen latest toots! by blackspike (@blackspike) on CodePen.
If you need help with adding a custom feed to your site, do get in touch!