38

I would like to register a URL scheme (or protocol) handler for my own custom URL protocol, so that clicking on a link with this custom protocol will execute a command on that URL. Which steps do I need to take to add this handler?

Example: I want to open URLs like ddg://query%20terms in a new DuckDuckGo browser search. If this protocol already exists, I assume that the steps to override a handler don't differ much from the steps to create a new one. Yes, technically, this is just a URL scheme, not a protocol.

palswim
  • 4,919
  • 6
  • 37
  • 53

2 Answers2

52

To register a new URL scheme handler with XDG, first create a Desktop Entry which specifies the x-scheme-handler/... MIME type:

[Desktop Entry]
Type=Application
Name=DDG Scheme Handler
Exec=open-ddg.sh %u
StartupNotify=false
MimeType=x-scheme-handler/ddg;

Note that %u passes the URL (e.g. ddg://query%20terms) as a single parameter, according to the Desktop Entry Specification.

Once you have created this Desktop Entry and installed it (i.e. put it in the local or system applications directory for XDG, like ~/.local/share/applications/ or /usr/share/applications/), then you must register the application with the MIME type (assuming you had named your Desktop Entry ddg-opener.desktop):

xdg-mime default ddg-opener.desktop x-scheme-handler/ddg

A reference implementation of the ddg-open.sh handler:

#!/usr/bin/env bash

# bash and not just sh because we are using some bash-specific syntax

if [[ "$1" == "ddg:"* ]]; then
    ref=${1#ddg://}
    #ref=$(python -c "import sys, urllib as ul; print ul.unquote_plus(sys.argv[1])" "$ref") # If you want decoding
    xdg-open "https://duckduckgo.com/?q=$ref"
else
    xdg-open "$1" # Just open with the default handler
fi
polypoyo
  • 5
  • 6
palswim
  • 4,919
  • 6
  • 37
  • 53
  • I was able to piece together this answer from [this Question](https://unix.stackexchange.com/q/55214/13308) and [its Answer](https://unix.stackexchange.com/a/100736/13308), but I wanted to make a more generic question and guide. – palswim Jan 28 '19 at 07:32
  • For the handler, [you can add encoding and decoding of the URL and parameters through Python](https://unix.stackexchange.com/a/159254/13308). – palswim Jan 28 '19 at 07:34
  • Is there a way to check if a protocol has a URL scheme handler registered? – Aaron Franke Jul 05 '22 at 04:20
1

If you have mimeo installed, and you already know the name of the Desktop file for the app you want to create the association for, it is as easy as doing:

mimeo --add 'x-scheme-handler/ddg' <path or name of desktop file>

For example, if duckduckgo, desktop file is at /usr/share/applications/Duckduckgo.desktop, then you just need:

mimeo --add 'x-scheme-handler/ddg' Duckduckgo

OR

mimeo --add 'x-scheme-handler/ddg' /usr/share/applications/Duckduckgo.desktop
smac89
  • 1,279
  • 1
  • 13
  • 17
  • How does the system know what ddg corresponds to? I want to make Steam URLs entered into the browser or clicked on open in the native Steam app. I asked this on reddit and got a similar answer but I broke steam's .desktop file until I reverted the change. https://www.reddit.com/r/linux_gaming/comments/yh0iou/comment/iubo507/?utm_source=share&utm_medium=web2x&context=3 – Deoxal Oct 30 '22 at 17:49
  • @Deoxal In the context of a URI, the `ddg` part is called the scheme, and is usually the first part of the uri. In most cases the scheme also corresponds to the protocol used to resolve the given resource. For example in the uri `https://google.com`, the `https` is the scheme, so the default browser app will be used to handle such a scheme. The app that should handle the protocol has to know how to do so for the above to work. For example, zoom recognizes the `zoommtg` or `zoomus` scheme, so when I try to access a zoom link on Firefox, it may prompt me to open the `zoom` app. – smac89 Oct 31 '22 at 02:02
  • @Deoxal to answer the second part of your question, your system does not directly handle the clicked link. It is up to the app in which the link was clicked to decide how to resolve the uri. Like I said, Firefox does this for `zoommtg` links because it actually checks for mimetype handlers. When it discovers which application should be invoked to handle to uri, it will then invoke that app or tell you that there is nothing available to handle it. – smac89 Oct 31 '22 at 02:07
  • @Deoxal Finally, you shouldn't have to modify `steam`'s desktop files to make sure `steam` handles the `steam` uri, unless the version of steam installed on your machine does not already come with a proper `.desktop` file. However, like I said, it is up to the application in which the link is clicked to find an appropriate way of handling the scheme. Firefox for sure does this, so if you're using Firefox and it is not doing that for you, then you need to ask a different question. Steam handles [these protocols](https://developer.valvesoftware.com/wiki/Steam_browser_protocol), if that helps. – smac89 Oct 31 '22 at 02:25