Bookmarks Booster Script

If like me, you've collected hundreds of browser bookmarks for each website under the sun over the years, you may find it a bit slow to search through all those bookmarks within your web browser to find what you're looking for. The Brave browser does have a built-in bookmarks search, but what if I told you that there is a faster way to search them?

Integration

After having moved to using a tiling window manager from a regular desktop, I tend to do everything from launching/closing apps to moving windows around using hotkeys. I don't always have a web browser open all the time while I'm working as I find it too distracting. Sometimes, however, I may need to access an online reference page, so it's handy to have these bookmarks easily accessible.

With this in mind, I decided to create a bash script which I could activate via a hotkey, which would read my saved bookmarks and present me with a Rofi search menu. I wanted the script to read the bookmarks from within the Brave folder, rather than me having to export them to a separate text file.

Looking At The Data

After having located where Brave saves its bookmark data, I noticed that the file is in JSON (JavaScript Object Notation) format. This is really handy for morons like me, as JSON is human-readable, and it makes looking for information to extract from them quite easy.

1cd ~/.config/BraveSoftware/Brave-Browser/Default/
2cat Bookmarks

Below is a small snippet of the Brave bookmarks file as shown in cat.

 1 {
 2    "checksum": "a456873987acf698741b4f2f1d55321771d",
 3    "roots": {
 4       "bookmark_bar": {
 5          "children": [ {
 6             "children": [ {
 7                "date_added": "13236805777000000",
 8                "guid": "64fd6f7d-119b-4842-beb0-0651142b4cea",
 9                "id": "6",
10                "name": "ArchWiki",
11                "type": "url",
12                "url": "https://wiki.archlinux.org/"
13             }, {
14                "date_added": "13230538882000000",
15                "guid": "787162a2-774a-4a80-bf23-df223d2603be",
16                "id": "7",
17                "name": "libvirt - ArchWiki",
18                "type": "url",
19                "url": "https://wiki.archlinux.org/title/Libvirt"
20             }, {
21                "date_added": "13230538897000000",
22                "guid": "65b5730d-4aca-4405-bb4e-76ab553606c4",
23                "id": "8",
24                "name": "KVM - ArchWiki",
25                "type": "url",
26                "url": "https://wiki.archlinux.org/title/KVM"
27             } ],

Bookmark Folders

I'm pretty tidy when I save bookmarks in my browser - I like to store my bookmarks in folders, named according to the category they fall into: "Arch", "Art", "Awesome", "Blender", "Comics", "Computing", "Gaming", "GitLab", "Linux"... you get the idea.

Looking at how the data is presented in the Bookmarks file, I noticed that I could pull URLs out using a command-line JSON processing tool called jq. This is available on most if not all Linux distributions, so you should be able to install it.

Using Arch Linux, it's super easy:

1yay -S jq

I'm looking to display just a list of URLs which I can search through in "Rofi", so let's see what output we get when we run the jq command on the Bookmarks file.

Let's cat the Bookmarks file into jq and then into head with a line count of 40.

1cat Bookmarks | jq . | head -n32 

By declaring a bookmarks variable in our shell, we can then manipulate the data by piping it through jq. I noticed that the Bookmarks data has a number of objects .roots[].children[] that need to be processed for this to work.

1BRAVE_BOOKMARKS=$HOME/.config/BraveSoftware/Brave-Browser/Default/Bookmarks
2
3echo $BRAVE_BOOKMARKS
4/home/supa/.config/BraveSoftware/Brave-Browser/Default/Bookmarks
5
6jq -cr '.roots[]?.children[]?.children[]? | {url}' $BRAVE_BOOKMARKS

Using what we've learned on how to process the data, we can then use some piping to get the result we desire:

1jq -cr '.roots[]?.children[]?.children[]? | {url} | join(" 🌐 ")' $BRAVE_BOOKMARKS | sort -u | rofi -i -dmenu -show -width 1500 -sorting-method fzf -l 20 -p 'Brave Bookmarks'

If you entered the above example correctly you should see a Rofi menu containing a list of all your Brave links.

The Bookmark Booster Script

Now, let's wrap all this up into a script which we can execute via a hotkey.

 1#!/bin/env bash
 2
 3# Default Brave bookmarks file location.
 4BRAVE_BOOKMARKS=$HOME/.config/BraveSoftware/Brave-Browser/Default/Bookmarks
 5
 6# Use jq to filter the urls and pipe into rofi
 7url=$(jq -cr '.roots[]?.children[]?.children[]? | {url} | join(" 🌐 ")' $BRAVE_BOOKMARKS | sort -u |rofi -i -dmenu -show -width 1500 -sorting-method fzf -l 20 -p 'Brave Bookmarks')
 8
 9# If user doesn't pick anything then exit here.
10if [[ -z "${url// }" ]]; then
11    exit 1
12fi
13
14# Launch Brave browser and feed it the selected URL from Rofi.
15brave $url

We can save this script using our favourite text editor and make it executable:

Save the file to ~/.scripts/rofi_brave_bookmarks.sh

1cd ~/.scripts/
2chmod +x rofi_brave_bookmarks.sh

Next, do a test run on the script:

1./rofi_brave_bookmarks.sh

If you see the Rofi menu and your selected URL was loaded in Brave, you can now add this script link to your sxhkdrc config file:

1vim ~/.config/sxhkdrc/sxhkdrc
1#.config/sxhkdrc/sxhkdrc
2
3# Brave bookmarks
4super + shift + b
5    ~/.scripts/rofi_brave_bookmarks.sh

Don't forget to reload your sxhkdrc file for the changes to work.

Wrapping Up

Personally, I find locating one among hundreds of bookmarks using this method far quicker than using the built-in Brave bookmark manager. If I add or remove URLs from within Brave, the script doesn't need to be changed as it works directly with the existing Brave bookmarks file. This is far simpler than having to export bookmarks to a separate text file every time I need to add or remove links.

I'm sure this method could be applied to other popular web browsers too with a little tinkering.

For those wishing to use, edit or improve upon it - I've provided a link to my full script over at my dotfiles repository on GitLab.