How to register a url protocol handler in Node.js

Daniel Chatfield picture Daniel Chatfield · Aug 30, 2013 · Viewed 11.5k times · Source

I am developing a command line node module and would like to be able to launch it via links on a website.

I want to register a custom protocol my-module:// such that links would have the following format: my-module://action:some-action and clicking on them would start the node package.

If there isn't a node API for this (I'm sure there won't be) then is there a way I can do it from node by invoking system commands?

It must work on Windows, Linux, and MacOS.

Answer

jeremy picture jeremy · Nov 4, 2013

Its an interesting idea. I don't think there is currently a cross platform node.js solution out there. I did come across this thread of people asking for the same thing:

https://github.com/rogerwang/node-webkit/issues/951

Electron now supports it with the app.setAsDefaultProtocolClient API (since v0.37.4) for macOS and Windows.

It wouldn't be terribly difficult to write the library to do this.

Windows:

On the windows side you'd have to register the app as the application that handles that URI scheme.

You'll need to set up a registry entry for your application:

HKEY_CLASSES_ROOT
   alert
      (Default) = "URL:Alert Protocol"
      URL Protocol = ""
      DefaultIcon
         (Default) = "alert.exe,1"
      shell
         open
            command
               (Default) = "C:\Program Files\Alert\alert.exe" "%1"

Then, when your application is run by windows, you should be able to see the arguments in process.argv[]. Make sure that you launch a shell to run node, not just your application directly.

Original MSDN article

Note this requires administrator privileges and sets the handler system-wide. To do it per user, you can use HKEY_CURRENT_USER\Software\Classes instead, as the Electron's implementation does it.

Apple:

The cited "OS X" article in the github comment is actually for iOS. I'd look at the following programming guide for info on registering an application to handle a URL scheme:

Apple Dev Documentation

In summary, you'll need to create a launch service and populate the .plist file with CFBundleURLTypes, this field is an array and should be populated with just the protocol name i.e. http

The following Super User Question has a better solution, but is a per user setting.

"The file you seek is ~/Library/Preferences/com.apple.LaunchServices.plist.

It holds an array called LSHandlers, and the Dictionary children that define an LSHandlerURLScheme can be modified accordingly with the LSHandlerRole."

Linux:

From what I can tell, there are several ways to accomplish this in Linux (surprise?)

Gnome has a tool that will let you register a url handler w3 archives

gconftool-2 -t string -s /desktop/gnome/url-handlers/tel/command "bin/vonage-call %s"
gconftool-2 -s /desktop/gnome/url-handlers/tel/needs_terminal false -t bool
gconftool-2 -t bool -s /desktop/gnome/url-handlers/tel/enabled true

Some of the lighter weight managers look like they allow you to create fake mime types and register them as URI Protocol handlers.

"Fake mime-types are created for URIs with various scheme like this: application/x-xdg-protocol- Applications supporting specific URI protocol can add the fake mime-type to their MimeType key in their desktop entry files. So it's easy to find out all applications installed on the system supporting a URI scheme by looking in mimeinfo.cache file. Again defaults.list file can be used to specify a default program for speficied URI type." wiki.lxde.org

KDE also supports their own method of handling URL Protocol Handlers:

Create a file: $KDEDIR/share/services/your.protocol and populate it with relevant data:

[Protocol]
exec=/path/to/player "%u"
protocol=lastfm
input=none
output=none
helper=true
listing=
reading=false
writing=false
makedir=false
deleting=false

from last.fm forums of all places

Hope that helps.