fredrik.lanker.se

Custom commands in Firefox with Tridactyl

2026-02-20

The scenario

You're on a web page and you want to extract some content from it and use it in an external command. Or a more specific use case, you use Miniflux as your feed reader to follow some podcasts and you want to play those podcasts in MPD. You use Firefox as your browser together with Tridactyl and Native Messaging. mpc will be used for controlling MPD.

The solution

The audio part for a podcast is rendered as an <audio> element in Miniflux. An <audio> element looks something like this:

<audio ...>
    <source src="https://example.com/sound.mp3" ...>
</audio>

So to get the URL to the audio file, we select the src attribute of the <source> element. For our use case, we know that we'll only have one of these elements, so we're happy with just getting the first one:

js document.querySelector("source").src

The output is then piped to the shellescape method using the special variable JS_ARG, which contains the result from the previous command (shown on two lines for clarity):

js document.querySelector("source").src |
js -p tri.excmds.shellescape(JS_ARG)

The -p flag is needed for JS_ARG to work.

Lastly, we call our external command with the escaped URL as an argument. shellescape returns a promise, so we need to handle that. We also need to prefix everything with composite, to make the pipe work. Combining everything and creating a new command, this is the final line that goes into our ~/.tridactylrc (or wherever you keep it) file:

command pod2mpd composite js document.querySelector("source").src | js -p tri.excmds.shellescape(JS_ARG).then(url => tri.excmds.exclaim_quiet('mpc add ' + url))

Finally we bind a key sequence to the command:

bind ,p pod2mpd

Now, pressing ,p will find the first source element on the current page and add its URL to MPD. This could, of course, be altered to instead send the link to another media player, download the file, or call an external script for more advanced handling (perhaps selecting multiple elements on the page, extracting links and selecting among them using fzf), and so on. Lots of possibilities!

feed github mastodon listenbrainz matrix