How I Navigate Hundreds of Tabs on Chrome with JXA and Alfred

8 min read Original article ↗

A New Project is Born: Chrome Control

I gathered everything under a project and named it Chrome Control. Perhaps someone can use it to integrate it with their favorite tool. Perhaps a vim or fzf integration? You can find the source code on GitHub.

Here’s what Chrome Control looks like:

Now that I had a way to do everything I needed, it was time for using Chrome Control via the best productivity app in the multiverse: Alfred.

Seriously, Apple should consider acquiring Alfred and deprecating Spotlight.

Using Chrome Control with Alfred

Alfred is one of the best productivity applications out there. It makes me 10x productive 🦄 at work without exaggeration. I have created dozens of workflows that help speed up my day-to-day tasks.

For this project, my dream was to hit alt + t anywhere in MacOS and start typing a tab title to instantly see a list of tabs filtered by fuzzy search, then I would simply highlight the tab I want and hit enter instantly to go to that tab.

First, I needed to create a new workflow in Alfred.

Press enter or click to view image in full size

Creating a new workflow

I made Chrome Control output the list of tabs as JSON for enabling integrations. This helps because if I wanted to list the tabs in Alfred, I had to use a Script Filter, and a Script Filter requires JSON output with some additional special fields.

Here’s a sample output of the list command:

{
"items": [
{
"title": "Inbox (1) - <hidden>@gmail.com - Gmail",
"url": "https://mail.google.com/mail/u/0/#inbox",
"winIdx": 0,
"tabIdx": 0,
"arg": "0,0",
"subtitle": "https://mail.google.com/mail/u/0/#inbox"
},
{
"title": "iPhone - Apple",
"url": "https://www.apple.com/iphone/",
"winIdx": 0,
"tabIdx": 1,
"arg": "0,1",
"subtitle": "https://www.apple.com/iphone/"
}
]
}

The arg and subtitle fields are required for the Script Filter. We’ll get into that in a bit.

Press enter or click to view image in full size

Adding a new Script Filter to the workflow

Creating a script filter opens up this window:

Press enter or click to view image in full size

Setting up the Script Filter

I wanted the keyword to be tabs so whenever I type tabs I’d see a list of all tabs in all windows.

There’s a bunch of other things that are going on here. First thing to notice is the with space argument optional. This tells Alfred to expect only the tabs command or an optional argument such as tabs apple which can show all Apple related tabs.

Alfred has a wonderful out-of-the box fuzzy search feature. To enable that, I simply checked the Alfred filters results checkbox.

On the script section, I told Alfred to run my list command.
And finally, I dragged the icon I created with Photoshop.

Here’s what the output looks like:

Chrome Control on Alfred

The second step is to bind the alt + t key to this command. Doing that is super simple in Alfred using the hotkey trigger:

Creating a Hotkey Trigger

Set it up to be alt + t:

Press enter or click to view image in full size

Setting up the Hotkey Trigger

Then connect it to the Script Filter by dragging the connection cable:

Press enter or click to view image in full size

Connecting the Hotkey Trigger to the Script Filter

Now that I had a way to hit a hotkey and filter a tab, it was time to focus on the selected tab when I hit enter.

Focusing on a Selected Tab

This part was a little tricky to get it work. I needed to tell Alfred to run another script with the result of the Script Filter.

Remember the arg value that I output in the JSON? It looked something like 0,1. The first value is the Window Index and the second value is the Tab Index. I needed to pass this arg value to the ./chrome.js focus command.

Luckily Alfred uses this arg value to pass it down as a {query} template variable to further actions that you connect to the Script Filter.

This means I can connect the output of the Script Filter to a new Run Script action, and pass the arg value to the focus command.

Press enter or click to view image in full size

Connecting the Script Filter output to a Run Script action

Then simply run the ./chrome.js focus {query} command whenever an item is selected from the list.

Press enter or click to view image in full size

Configuring the Script Filter to run the `focus` command when an item is selected

And it worked!

I also wanted a way to close the highlighted tabs. For this, I could use the alt key, which is the modifier key in MacOS.

If you didn’t know this feature try clicking on your wifi icon or the speaker icon in the menu bar while holding the alt key, for some additional features.

For that to happen, I needed to connect the Script Filter to my close command.

Press enter or click to view image in full size

Connecting the tabs command to the Chrome Control close command

To tell Alfred that this script should run only when the alt key is pressed, you need to right click on the connection and configure it.

Opening the connection configuration

Press enter or click to view image in full size

Setting up the alt key behavior

I wanted the Close this tab text to appear when I hold the alt key. The result looks like this:

Press enter or click to view image in full size

Holding `alt` and hitting enter will close this tab

Once this was done, I was hungry to add more features. That’s when I thought of doing something about my duplicate tabs problem.

Deduping Open Tabs

One of my main problems was duplicate tabs. To solve that issue, I wanted to add a dedup command to Chrome Control.

It simply iterates all the open tabs, finds the duplicates, then closes them.

One small problem though, I thought it would be a disaster if I accidentally closed a tab which had unsaved work, such as a semi-filled form, an unsaved doc, half written email, … etc.

For that reason I wanted a prompt that showed me a list of tabs that were about to get closed and ask me if I was really sure about closing them. I made this the default option, and added a --yes flag, so if I ever wanted to force all the tabs to be closed without a prompt, I could.

Here’s an example of deduping five Hacker News tabs I’ve opened:

Press enter or click to view image in full size

Deduping tabs with Chrome Control

I then connected this to Alfred. But then I realized that I needed a prompt inside the browser now. So I added a --ui flag. When this flag is provided, Chrome Control will ask the questions inside the browser instead of the terminal.

Press enter or click to view image in full size

Connecting the dedup command to Chrome Control

I simply created a keyword trigger then connected to ./chrome.js dedup. Now a dialog appears on Chrome to ask me if I’m sure!

Press enter or click to view image in full size

Chrome asking me if I’m sure about closing the duplicate tabs

This is why we added the following line all the way at the beginning of our script. It allowed us to show this dialog.

chrome.includeStandardAdditions = true

Closing Tabs by Keywords

One other feature I really wanted was to close tabs by keywords. The keywords could exist in the url or the title of the tab.

For instance if I had a gazillion Google Docs open, I could simply type ./chrome.js close --url docs.google. Chrome Control would then find all the urls that included this string and close the tabs.

I also wanted this to work with tab title as well. For instance, if I was doing a research about the latest iPhone, perhaps I could bulk close all the titles that included iPhone such as ./chrome.js close --title iphone.

So I went ahead and implemented those two commands as well.

Press enter or click to view image in full size

Closing tabs by title

Press enter or click to view image in full size

Closing tabs by URL

These commands can take multiple keywords divided with a space. Or if the phrase itself includes a space then wrapping the phrase with double quotes would work, such as "this is a phrase with spaces".

And of course I connected them to Alfred. This time an argument was required.

Press enter or click to view image in full size

Connecting the `Close URL` command with Alfred

And then added a Run Script action and this time used with input as argv. This allowed me to use $@ which sends all the keywords I typed to Chrome Control as arguments.

Press enter or click to view image in full size

Setting up the `close url` command on Alfred

Press enter or click to view image in full size

Connecting the `close url` keyword to Chrome Control

Here’s how I close all the tabs that contain apple or doc in them.

Press enter or click to view image in full size

Closing tabs with URLs that contain either `apple` or `doc`

I repeated the same for creating a close title command on Alfred.

I also added additional hotkeys to trigger other commands:

  • alt + t List all tabs
  • alt + d Dedup tabs
  • alt + c Close tabs by URL
  • alt + shift + c Close tabs by title

And here’s what the final workflow looks like: