Abhinav's Notes

Customizing Miniflux to Be a Two-Pane Feed Reader

I have been using Reeder on my laptop as my feed reader app backed by Miniflux for the last couple of years. Recently, I found myself often clicking away from Reeder to the original blog posts in the browser.

I realised that most of the blogs I follow do not need sanitisation as done by feed readers because they are usually well-designed and do not contain ads. In fact, some of them are great looking, and have their own unique looks. I noticed that I prefer reading them in the browser, in their full glory, with their different styles, instead of all of them looking same black-and-white minimal-styled text in the reading pane of Reeder.

So, I went out looking for a feed reader that manages subscriptions like usual, but instead of having its own reading pane, opens the articles in a side-by-side browser pane. And I found none. Not a single feed reader I could find with links displayed in a sidebar, and original posts in a browser pane.

So I hacked my own using some custom CSS and JS added to the Miniflux UI:

Screenshot of my custom Miniflux based two-pane feed reader Screenshot of my custom Miniflux based two-pane feed reader

Now, when I click on a link in Miniflux, the link opens in another window that I can place by the side of the Miniflux window. Clicking on any other link in Miniflux also opens its website in the same window so a new window is not opened everytime1. Opening a link also marks it as read in Miniflux.

Sometime I want to read certain entries inside the Miniflux reader instead. Clicking on a link with the Command button pressed opens the link inside the Miniflux reader in the same reader window as before2.

This also allows me to customize each website using various Firefox extensions. I can remove various parts of pages if required using uBlock Origin, I can turn pages dark using Dark reader, or restyle them using Stylus, or even change their functionality using Tampermonkey scripts. All of this is great!

I’ve had this setup for three months now, and I’m loving it. I have stopped using Reeder altogether!

Here is the custom CSS I set in my Miniflux settings:
body {
  max-width: 55em;
}
.item {
  border: none;
}
.item-title {
  font-size: 1.2rem;
}
.item-meta {
  display: flex;
  justify-content: space-between;
}
.item-meta a {
  color: #AAA;
}
.item-meta-icons li > :is(a, button) {
  color: #AAA;
}
.item-meta-icons :is(a:is(:focus, :hover), button:is(:focus, :hover)) {
  color: lightsalmon;
}
.item-meta-info :is(a:is(:focus, :hover), button:is(:focus, :hover)) {
  color: lightblue;
}
.item-meta-icons li {
  margin-top: 0;
}
.item-meta .item-meta-icons-comments {
  display: none;
}
.item-meta-icons .item-meta-icons-external-url {
  margin-right: 0;
  display: none;
}
.item-meta-info {
  font-size: inherit;
}
.item-header .category {
  position: relative;
  bottom: 0.2em;
}
.item-header h2 a img {
  background-color: #eee;
}
.entry header h1, .entry header .entry-actions, .entry header .entry-meta {
  margin-bottom: 10px;
}
.entry-content pre {
  padding: 5px 10px;
}
.entry-content code {
  font-size: 0.95em;
}
.entry-actions :is(.page-button, .page-link) {
  &:is(:hover, :focus) {
    color: lightsalmon;
  }
}
.header {
  position: sticky;
  top: 0;
  background-color: var(--body-background);
  z-index: 2;
  padding-bottom: 0.5rem;
}
.page-header, section.entry {
  position: sticky;
  top: calc(0.9rem + 10px);
  background-color: var(--body-background);
  z-index: 2;
  padding-bottom: 0.5rem;
}
.header li a:hover, .entry header h1 a:hover, .page-header h1 a:hover {
  color: var(--link-hover-color);
}
:root {
--entry-content-color: #BABABA;
--body-background: #141414;
--entry-content-code-color: #dfdfdf;
--entry-content-code-background: #222;
--entry-content-code-border-color: transparent;
--category-link-hover-color: lightblue;
--category-has-unread-background-color: unset;
--category-has-unread-border-style: unset;
--category-has-unread-border-color: unset;
--feed-parsing-error-border-style: unset;
--feed-parsing-error-border-color: unset;
--feed-has-unread-background-color: unset;
--feed-has-unread-border-style: unset;
--feed-has-unread-border-color: unset;
}

Along with other small style tweaks as per my taste, this positions actions buttons for entries on the right, hides links for entry comments and external URLs, and makes the page headers sticky so that they stay visible even when you scroll down.

Here is the Tampermonkey script I use for changing Miniflux's default behaviour:
// ==UserScript==
// @name         Miniflux 2 Pane
// @match        https://reader.miniflux.app/*
// ==/UserScript==

(function() {
  'use strict';

  function openArticle(article, openInMinifluxReader) {
    let articleURL = openInMinifluxReader
      ? article.querySelector(".item-header h2 a").href
      : article.querySelector(".item-meta-icons-external-url a").href;
    if (window.open(articleURL, "miniflux-viewer")) {
      article
        .querySelector(".item-meta-icons-read button[data-value=unread]")
        .click();
    }
  }

  document.addEventListener("DOMContentLoaded", () => {
    document.querySelectorAll(".entry-item .item-title a").forEach(a => {
      a.addEventListener("click", function(ev) {
        ev.preventDefault();
        let article = a.parentElement.parentElement.parentElement;
        openArticle(article, ev.metaKey);
      });
    });
  });

})();

That’s it! This works very well for me, and I hope this helps someone else too.

Like, share, or comment on this post on Mastodon.

  1. This works most of the time, but breaks for some websites that override their window name upon opening. 

  2. Unfortunately, I was not able to figure out how to make this work with Miniflux’s keyboard navigation.