Robert Birming

Bear blog comments via Micro.blog

I recently added a Micro.blog add-ons category for my Bearming theme, and it now includes an add-on for showing replies on your Bear blog.

If one of your posts got a reply, it will be displayed below the upvote button. Each reply shows as a card with the author's avatar, name, message, and a link to the original reply. Here's an example from the Photo calendar for Bear blog post. If there are no replies, the post will look just like before.1 2 3

The add-on requires that your Bear blog feed is imported into Micro.blog.

Preview

Micro.blog replies

How to use

Add the script to your blog footer. Replace the config values at the top with your own domains and Micro.blog username.

Script

<script>
/* Micro.blog replies | robertbirming.com */
(async () => {
  const BEAR_DOMAIN = 'your-bearblog.com';
  const MB_DOMAIN = 'your-microblog.com';
  const MB_USERNAME = 'your-microblog-username';

  const url = window.location.href.replace(BEAR_DOMAIN, MB_DOMAIN).split('#')[0];
  const endpoint = 'https://micro.blog/conversation.js?url=' + encodeURIComponent(url) + '&format=jsonfeed';
  try {
    const res = await fetch(endpoint);
    if (!res.ok) return;
    const { items } = await res.json();
    if (!items?.length) return;
    const container = document.createElement('div');
    container.className = 'mb-replies';
    container.id = 'replies';
    container.innerHTML = '<h4 class="mb-replies-heading">Replies</h4>' +
      items.map(item => {
        const a = item.author || {};
        const name = (a.name || '').replace(/:[a-z0-9_]+:/g, '').trim();
        const pubDate = new Date(item.date_published);
        const label = pubDate.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' });
        const nameEl = a.url
          ? '<a class="mb-reply-name" href="' + a.url + '" rel="noopener">' + name + '</a>'
          : '<span class="mb-reply-name">' + name + '</span>';
        const timeEl = item.url
          ? '<a class="mb-reply-time" href="' + item.url + '" rel="noopener">' + label + '</a>'
          : '<span class="mb-reply-time">' + label + '</span>';
        return '<div class="mb-reply">' +
          '<img class="mb-reply-avatar" src="' + (a.avatar || '') + '" alt="' + name + '" width="32" height="32">' +
          '<div class="mb-reply-body">' +
            nameEl +
            '<div class="mb-reply-text">' + (item.content_html || '') + '</div>' +
            timeEl +
          '</div>' +
        '</div>';
      }).join('') +
      '<p class="mb-replies-footer">via <a href="https://micro.blog/' + MB_USERNAME + '" rel="noopener">Micro.blog</a></p>';
    const upvote = document.querySelector('#upvote-form');
    if (upvote) {
      const curve = document.createElement('span');
      curve.className = 'curve';
      upvote.insertAdjacentElement('afterend', container);
      upvote.insertAdjacentElement('afterend', curve);
    } else {
      document.querySelector('main').appendChild(container);
    }
    if (window.location.hash === '#replies') {
      setTimeout(() => container.scrollIntoView({ behavior: 'smooth' }), 100);
    }
  } catch (e) {
    console.warn('MB replies:', e);
  }
})();
</script>

Styles

/* Micro.blog replies | robertbirming.com */
.mb-replies {
  margin-block-start: var(--space-block);
}

.mb-replies-heading {
  display: flex;
  align-items: center;
  gap: 0.4em;
  margin-block: var(--space-block) 1rem;
}

.mb-replies-heading::before {
  content: "💬";
  translate: 0 1px;
}

.mb-reply {
  display: flex;
  gap: 0.8rem;
  align-items: flex-start;
  margin-block-end: 1.2rem;
  padding-block: 1rem;
  padding-inline: 1.2rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.mb-reply-avatar {
  flex-shrink: 0;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  object-fit: cover;
  margin: 0;
  margin-block-start: 0.2rem;
}

.mb-reply-body {
  min-width: 0;
}

.mb-reply-name {
  display: block;
  margin-block-end: 0.35em;
  font-size: 1rem;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
}

.mb-reply-name:visited {
  color: var(--text);
}

@media (hover: hover) {
  .mb-reply-name:hover {
    color: var(--link);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
  }
}

.mb-reply-text {
  font-size: 1rem;
}

.mb-reply-text p {
  margin-block: 0.3em;
}

.mb-reply-text > :first-child {
  margin-block-start: 0;
}

.mb-reply-time {
  display: inline-block;
  margin-block-start: 0.6em;
  font-size: calc(var(--font-small) * 0.85);
  color: var(--muted);
  text-decoration: none;
}

.mb-reply-time:visited {
  color: var(--muted);
}

@media (hover: hover) {
  .mb-reply-time:hover {
    color: var(--link);
  }
}

.mb-replies-footer {
  margin-block-start: 0.2rem;
  font-size: var(--font-small);
  color: var(--muted);
}

Want more? Check out all available Bearming add-ons.

  1. Built for the Bearming theme (robertbirming.com/bearming/). Using a different theme? Add the Bearming tokens (robertbirming.com/bearming-tokens/) to make them work with your setup.

  2. Requires JavaScript, available on Bear Blog's premium plan.

  3. Not using Micro.blog? Here are some other Bear comments options.