This page looks best with JavaScript enabled

Linking Browser with External Software

 ·  🎃 kr0m

In this article, we will see how to configure a button in our browser to launch external software by passing it the current URL. This is especially useful when we want to use CLI tools.

In my case, I’m going to automate video downloads. For this, we’ll use yt-dlp, so let’s install it:

apt install yt-dlp

We prepare the script that the browser will call. As we can see, it’s just a bit of Zenity asking for the path to save the file and some additional checks:

vi ~/.scripts/yt-dlp-auto.sh
#!/usr/bin/env bash

URL="$1"

if [ -z "$URL" ]; then
    notify-send -t 8000 "yt-dlp" "No URL provided"
    exit 1
fi

# Try to get video title with dump-json (10s timeout)
TITLE=$(timeout 10 yt-dlp --no-playlist --dump-json "$URL" 2>/dev/null | jq -r .title)

# Replace problematic characters (allow alnum, ., _, -, space → spaces → _)
SAFE_TITLE=$(echo "$TITLE" | sed 's/[^[:alnum:]._ -]//g; s/[ ]/_/g')

# Fallback if empty
if [ -z "$SAFE_TITLE" ]; then
    SAFE_TITLE="video"
    notify-send -t 5000 "yt-dlp" "⚠️ Could not fetch video title, using default name"
fi

# Ask where to save the file in a loop
while true; do
    OUTPUT_PATH=$(zenity --file-selection --save --confirm-overwrite \
        --filename="${SAFE_TITLE}.mp4" \
        --title="Save video as:")

    # Exit if user cancelled
    if [ -z "$OUTPUT_PATH" ]; then
        notify-send -t 8000 "yt-dlp" "Download cancelled"
        exit 1
    fi

    # Check if partial file exists
    if [ -f "${OUTPUT_PATH}.part" ]; then
        zenity --warning --title="File exists" \
            --text="An active download already exists:\n$OUTPUT_PATH\n\nPlease choose another name."
        continue
    fi

    # If file already exists (not .part), remove it since user confirmed overwrite
    if [ -f "$OUTPUT_PATH" ]; then
        rm -f "$OUTPUT_PATH"
    fi

    # If path is safe, break loop
    break
done

# Prepare yt-dlp output template (strip extension → yt-dlp adds real one)
OUTPUT_TEMPLATE="${OUTPUT_PATH%.*}.%(ext)s"

# Run yt-dlp and capture the final filename
FINAL_PATH=$(yt-dlp -f "bv*+ba/b" -o "$OUTPUT_TEMPLATE" \
    --print after_move:filepath "$URL")
STATUS=$?

if [ $STATUS -eq 0 ]; then
    notify-send -t 10000 "yt-dlp" "Download completed: $FINAL_PATH"
else
    notify-send -t 10000 "yt-dlp" "Download failed: $URL"
fi

# Wait a moment to ensure process cleanup
sleep 2

# Check if there are any yt-dlp processes still running
if ! pgrep -x yt-dlp >/dev/null; then
    notify-send -i dialog-ok -t 0 "yt-dlp" "All downloads finished ✅"
fi

We assign the necessary permissions:

chmod 700 ~/.scripts/yt-dlp-auto.sh

The browser extension we’ll use is External Application Launcher .

Clicking the new icon will show a form. Basically, we need to indicate the program or script to execute, the arguments, where to position the button, and an icon:

Now we’ll see a new button. If we press it, it will inform us that we need to install the NodeJS native client:

We follow the instructions: download the archive, extract it, and run ./install.sh after reviewing its content:

unzip linux.zip
cat install.sh
./install.sh
Installer is using your system NodeJS.

 -> Root directory is /home/kr0m/.config
 -> Creating a directory at /home/kr0m/.config/google-chrome/NativeMessagingHosts
 -> Chrome Browser is supported
 -> Creating a directory at /home/kr0m/.config/chromium/NativeMessagingHosts
 -> Chromium Browser is supported
 -> Creating a directory at /home/kr0m/.config/vivaldi/NativeMessagingHosts
 -> Vivaldi Browser is supported
 -> Creating a directory at /home/kr0m/.config/BraveSoftware/Brave-Browser/NativeMessagingHosts
 -> Brave Browser is supported
 -> Creating a directory at /home/kr0m/.config/microsoftedge/NativeMessagingHosts
 -> Microsoft Edge Browser is supported
 -> Creating a directory at /home/kr0m/.mozilla/native-messaging-hosts
 -> Firefox Browser is supported
 -> Creating a directory at /home/kr0m/.waterfox/native-messaging-hosts
 -> Waterfox Browser is supported
 -> Creating a directory at /home/kr0m/.tor-browser/app/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts
 -> Tor Browser is supported
 -> Creating a directory at /home/kr0m/.thunderbird/native-messaging-hosts
 -> Thunderbird Email Client is supported
 -> Creating a directory at /home/kr0m/.config/com.add0n.node
 => Native Host is installed in /home/kr0m/.config/com.add0n.node


>>> host is ready <<<

Now we click the Check Connection button, and it should connect without problems:

Clicking the button again will execute our script: