Micro.blog feed
This Bearming add-on for Bear fetches and displays your latest posts from a Micro.blog JSON feed. Each note shows the post content, a linked date, and a reply count.1
Looking for a single-post widget? Check out the Micro.blog latest post add-on.
Preview
Head over to my notes page to see it in action.
How to use
Add the markup wherever you want the feed to appear, then add the script and styles to your theme. Replace the feed URL with your own Micro.blog JSON feed URL. Adjust data-limit to control how many posts are shown.
Markup
<section class="mb-feed"
data-feed="https://yoursite.com/feed.json"
data-limit="10">
<div class="mb-feed-list" aria-live="polite">
<p>Loading...</p>
</div>
</section>
Script
<script>
/* Micro.blog feed | robertbirming.com */
(async () => {
const root = document.querySelector('.mb-feed');
if (!root) return;
const list = root.querySelector('.mb-feed-list');
const feedUrl = root.getAttribute('data-feed');
const limit = parseInt(root.getAttribute('data-limit') || '10', 10);
if (!feedUrl) { list.innerHTML = '<p>Feed not configured.</p>'; return; }
async function fetchItems(url, max) {
const items = [];
let next = url;
while (next && items.length < max) {
try {
const res = await fetch(next);
if (!res.ok) break;
const data = await res.json();
items.push(...(data.items || []).filter(i => i?.content_html || i?.content_text));
next = data.next_url || null;
} catch { break; }
}
return items.slice(0, max);
}
async function fetchReplies(permalink, el) {
try {
const res = await fetch('https://micro.blog/conversation.js?url=' + encodeURIComponent(permalink) + '&format=jsonfeed');
if (!res.ok) throw new Error();
const data = await res.json();
const count = data.items?.length || 0;
const page = data.home_page_url || permalink;
el.innerHTML = '<a href="' + page + '" rel="noopener">' + (count > 0 ? count + ' ' + (count === 1 ? 'reply' : 'replies') : 'Reply') + '</a>';
} catch {
el.innerHTML = '<a href="' + permalink + '" rel="noopener">Reply</a>';
}
}
try {
const items = await fetchItems(feedUrl, limit);
if (!items.length) { list.innerHTML = '<p>No recent notes found.</p>'; return; }
list.innerHTML = '';
items
.sort((a, b) => new Date(b.date_published || 0) - new Date(a.date_published || 0))
.forEach(item => {
const card = document.createElement('article');
card.className = 'mb-feed-note';
const html = item.content_html || '<p>' + String(item.content_text).replace(/&/g, '&').replace(/</g, '<') + '</p>';
const permalink = item.url || '#';
const date = new Date(item.date_published || Date.now()).toLocaleDateString('en-GB', { year: 'numeric', month: 'short', day: 'numeric' });
card.innerHTML =
'<div class="mb-feed-content">' + html + '</div>' +
'<div class="mb-feed-meta">' +
'<a class="mb-feed-date" href="' + permalink + '" rel="noopener">' + date + '</a>' +
'<span class="mb-feed-replies"><a href="' + permalink + '" rel="noopener">Reply</a></span>' +
'</div>';
list.appendChild(card);
fetchReplies(permalink, card.querySelector('.mb-feed-replies'));
});
} catch {
list.innerHTML = "<p>Couldn't load notes right now.</p>";
}
})();
</script>
Styles
/* Micro.blog feed | robertbirming.com */
.mb-feed {
margin-block: var(--space-block);
}
.mb-feed-list {
display: grid;
gap: calc(var(--space-block) * 0.75);
}
.mb-feed-note {
padding-block: 0.9rem;
padding-inline: 1.1rem;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
}
.mb-feed-content {
font-size: var(--font-small);
color: color-mix(in srgb, var(--text) 85%, var(--bg));
overflow-wrap: break-word;
}
.mb-feed-content > :first-child { margin-block-start: 0; }
.mb-feed-content > :last-child { margin-block-end: 0; }
.mb-feed-content a {
overflow-wrap: break-word;
}
.mb-feed-content img {
border-radius: var(--radius);
}
.mb-feed-meta {
display: flex;
flex-wrap: wrap;
align-items: baseline;
justify-content: space-between;
gap: 0.35rem 1rem;
margin-block-start: 0.75rem;
padding-block-start: 0.65rem;
font-size: 0.75rem;
color: color-mix(in srgb, var(--text) 65%, var(--bg));
}
.mb-feed-meta a {
color: inherit;
text-decoration: none;
}
.mb-feed-meta a:visited {
color: color-mix(in srgb, var(--text) 60%, var(--bg));
}
@media (hover: hover) {
.mb-feed-meta a:hover {
color: var(--link);
}
}
.mb-feed-list > p {
margin-block: 0;
color: var(--muted);
}
Want more? Check out all available Bearming add-ons.
Happy blogging, and microblogging.
Built for the Bearming theme. Using a different theme? Add the Bearming tokens to make them work with your setup.↩