Custom protocol handlers allow websites or web applications to register themselves as handlers for specific custom URL schemes (e.g., web+myapp://). When a user clicks a link using such a protocol, the browser prompts them to choose a handler, and if approved, opens the registered web app or service.

How It Works

  • Web-based registration: Use navigator.registerProtocolHandler() in JavaScript to register a protocol. The protocol must start with web+ (e.g., web+myapp) or use a predefined one like mailto.

    if ('registerProtocolHandler' in navigator) {
      navigator.registerProtocolHandler(
        'web+myapp',
        'https://example.com/app?uri=%s',
        'My App'
      );
    }

    The %s placeholder is replaced with the full URL of the clicked link.

  • Manifest-based registration: For Progressive Web Apps (PWAs), define protocol_handlers in the manifest.json file:

    {
      "protocol_handlers": [
        {
          "protocol": "web+myapp",
          "url": "/app?uri=%s"
        }
      ]
    }

    This registers the PWA as a handler when installed on desktop platforms (Windows, Linux, Mac).

Supported Browsers

  • Chromium-based browsers (Chrome, Edge, etc.): Support custom protocols via registerProtocolHandler and manifest registration.

  • Firefox: Supports registerProtocolHandler since version 3.

  • Safari: Limited support; requires additional configuration.

Use Cases

  • App integration: Open a specific web app from a custom link (e.g., web+pwinter://3D3D3D-5A0FC8-3D3D3D).

  • File sharing: Handle magnet: links via web-based torrent clients.

  • Email or messaging: Redirect mailto: or sms: links to a preferred service.

  • Internal app navigation: Enable deep linking between web and installed PWAs.

Important Notes

  • Security: Users must explicitly approve the handler.

  • Private browsing: Extensions and handlers may not work in private browsing windows by default.

  • Platform-specific setup: On Windows, registration may require registry changes for non-web protocols (e.g., apphub:).

For more details, refer to MDN Web Docs and Microsoft Learn.

AI-generated answer. Please verify critical facts.
Top answer
1 of 7
96

The following method registers an application to a URI Scheme. So, you can use mycustproto: in your HTML code to trigger a local application. It works on a Google Chrome Version 51.0.2704.79 m (64-bit).

I mainly used this method for printing document silently without the print dialog popping up. The result is pretty good and is a seamless solution to integrate the external application with the browser.

HTML code (simple):

<a href="mycustproto:Hello World">Click Me</a>

HTML code (alternative):

<input id="DealerName" />
<button id="PrintBtn"></button>

$('#PrintBtn').on('click', function(event){
  event.preventDefault();
  window.location.href = 'mycustproto:dealer ' + $('#DealerName').val();
});

URI Scheme will look like this:

You can create the URI Scheme manually in registry, or run the "mycustproto.reg" file (see below).

HKEY_CURRENT_USER\Software\Classes
   mycustproto
      (Default) = "URL:MyCustProto Protocol"
      URL Protocol = ""
      DefaultIcon
         (Default) = "myprogram.exe,1"
      shell
         open
            command
               (Default) = "C:\Program Files\MyProgram\myprogram.exe" "%1"

mycustproto.reg example:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\mycustproto]
"URL Protocol"="\"\""
@="\"URL:MyCustProto Protocol\""

[HKEY_CURRENT_USER\Software\Classes\mycustproto\DefaultIcon]
@="\"mycustproto.exe,1\""

[HKEY_CURRENT_USER\Software\Classes\mycustproto\shell]

[HKEY_CURRENT_USER\Software\Classes\mycustproto\shell\open]

[HKEY_CURRENT_USER\Software\Classes\mycustproto\shell\open\command]
@="\"C:\\Program Files\\MyProgram\\myprogram.exe\" \"%1\""

C# console application - myprogram.exe:

using System;
using System.Collections.Generic;
using System.Text;

namespace myprogram
{
  class Program
  {
    static string ProcessInput(string s)
    {
       // TODO Verify and validate the input 
       // string as appropriate for your application.
       return s;
    }

    static void Main(string[] args)
    {
      Console.WriteLine("Raw command-line: \n\t" + Environment.CommandLine);
      Console.WriteLine("\n\nArguments:\n");

      foreach (string s in args)
      {
        Console.WriteLine("\t" + ProcessInput(s));
      }

      Console.WriteLine("\nPress any key to continue...");
      Console.ReadKey();
    }
  }
}

Try to run the program first to make sure the program has been placed in the correct path:

cmd> "C:\Program Files\MyProgram\myprogram.exe" "mycustproto:Hello World"

Click the link on your HTML page:

You will see a warning window popup for the first time.

To reset the external protocol handler setting in Chrome:

If you have ever accepted the custom protocol in Chrome and would like to reset the setting, do this (currently, there is no UI in Chrome to change the setting):

Edit "Local State" this file under this path:

C:\Users\Username\AppData\Local\Google\Chrome\User Data\

or Simply go to:

%USERPROFILE%\AppData\Local\Google\Chrome\User Data\

Then, search for this string: protocol_handler

You will see the custom protocol from there.

Note: Please close your Google Chrome before editing the file. Otherwise, the change you have made will be overwritten by Chrome.

Reference:

https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx

2 of 7
55

Chrome 13 now supports the navigator.registerProtocolHandler API. For example,

navigator.registerProtocolHandler(
    'web+custom', 'http://example.com/rph?q=%s', 'My App');

Note that your protocol name has to start with web+, with a few exceptions for common ones (like mailto, etc). For more details, see: http://updates.html5rocks.com/2011/06/Registering-a-custom-protocol-handler

🌐
Microsoft Learn
learn.microsoft.com › en-us › windows › win32 › search › -search-3x-wds-ph-install-registration
Installing and registering protocol handlers (Windows Search) - Win32 apps | Microsoft Learn
Installing protocol handlers involves copying the DLL(s) to an appropriate location in the Program Files directory, and then registering the DLL(s). Protocol handlers should implement self-registration for installation.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › API › Navigator › registerProtocolHandler
Navigator: registerProtocolHandler() method - Web APIs | MDN
The Navigator method registerProtocolHandler() lets websites register their ability to open or handle particular URL schemes (also known as protocols).
🌐
Microsoft Learn
learn.microsoft.com › en-us › office › dev › add-ins › publish › custom-protocol-handler
Trust custom protocol handlers that launch add-ins
A protocol handler lets an app or add-in launch from a URI (for example, clicking a mailto: link opens your email client). Office add-ins also launch this way. By default, users are prompted to trust each add-in and protocol pair.
🌐
Medium
medium.com › swlh › custom-protocol-handling-how-to-8ac41ff651eb
Custom Protocol Handling — How To | by Tal Martsiano | The Startup | Medium
27 December 2020 - Using custom protocols handler is a very nice way to run applications from browser or website, its commonly used if you need an engine/server to be run locally on the host machine for your site.
🌐
Google Support
support.google.com › chrome › thread › 14322141 › can-i-open-a-custom-protocol-handler-directly-without-being-asked-each-time
Can I open a custom protocol handler directly without being asked each time? - Google Chrome Community
Skip to main content · Google Chrome Help · Sign in · Google Help · Help Center · Community · Google Chrome · Terms of Service · Submit feedback · Send feedback on
🌐
Chrome Developers
developer.chrome.com › docs › web platform › url protocol handler registration for pwas
URL protocol handler registration for PWAs | Web Platform | Chrome for Developers
11 May 2021 - Just this time the information is passed declaratively via the web app manifest in a new property called "protocol_handlers" that takes an array of objects with the two required keys "protocol" and "url". The code snippet below shows how to register web+tea and web+coffee.
🌐
Microsoft Edge
blogs.windows.com › msedgedev › 2022 › 01 › 20 › getting-started-url-protocol-handlers-microsoft-edge
Getting started with Protocol Handlers for your web app - Microsoft Edge Blog
10 June 2025 - If the protocol_handlers field is present in the manifest, then during installation the web app will be registered as a protocol handler for the protocols specified in the collection. This field receives a collection of protocol and url pairs. The protocol specifies which scheme to register and the url tells the user agent which resource will process the URI. As an example we will look at the PWinter PWA. This is an installable web application that allows the user to create custom PWA logos by selecting 3 colors.
Find elsewhere
🌐
npm
npmjs.com › package › custom-protocol-handler
custom-protocol-handler - npm
Resolve custom protocols using registered handlers. Latest version: 3.0.1, last published: 6 years ago. Start using custom-protocol-handler in your project by running `npm i custom-protocol-handler`. There are no other projects in the npm registry using custom-protocol-handler.
      » npm install custom-protocol-handler
    
Published   Jan 12, 2019
Version   3.0.1
Author   Dario Vladovic
🌐
Web.dev
web.dev › articles › registering a custom protocol handler
Registering a custom protocol handler | Articles | web.dev
29 June 2011 - Chrome 13 finally includes navigator.registerProtocolHandler. This API allows web apps to register themselves as possible handlers for particular protocols.
🌐
Mozilla
developer.mozilla.org › en-US › docs › Web › Progressive_web_apps › Manifest › Reference › protocol_handlers
protocol_handlers - Web app manifest | MDN
A developer can add a field in the manifest.json to declare which protocols the web app can handle. As seen in the example above, the key is named protocol_handlers and it contains an array of protocol handler declaration objects.
🌐
Microsoft Learn
learn.microsoft.com › en-us › windows › win32 › search › -search-3x-wds-extidx-prot-implementing
Understanding protocol handlers - Win32 apps | Microsoft Learn
The items in a data store can be indexed by the Windows Search system using a protocol handler. The protocol handler implements the protocol for accessing a content source in its native format. The ISearchProtocol and ISearchProtocol2 interfaces are used to implement a custom protocol handler to expand the data sources that can be indexed.
Top answer
1 of 2
69

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
2 of 2
4

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
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Mozilla › Add-ons › WebExtensions › manifest.json › protocol_handlers
protocol_handlers - Mozilla | MDN
Each protocol handler has three properties, all mandatory: ... A string defining the protocol. This must be either: one of the following: "bitcoin", "dat", "dweb", "ftp", "geo", "gopher", "im", "ipfs", "ipns", "irc", "ircs", "magnet", "mailto", "matrix", "mms", "news", "nntp", "sip", "sms", "smsto", "ssb", "ssh", "tel", "urn", "webcal", "wtai", "xmpp". a string consisting of a custom name prefixed with "web+" or "ext+".
🌐
Can I Use
caniuse.com › registerprotocolhandler
Custom protocol handling | Can I use... Support tables for HTML5, CSS3, etc
Method of allowing a webpage to handle a given protocol using navigator.registerProtocolHandler.
🌐
Medium
medium.com › @walid.mougharbel › custom-protocol-handler-to-allow-opening-applications-from-browsers-4aea5d3b09b6
Custom Protocol Handler to allow opening applications from browsers | by Walid Mougharbel | Medium
9 March 2023 - Custom Protocol Handler: is an application that allows you to create a protocol handler with a protocol name that you specify, good example would be “apphub:” When the user clicks “apphub:” link, the browser opens the applicaton selected ...
🌐
GitHub
github.com › vladimyr › custom-protocol-handler
GitHub - vladimyr/custom-protocol-handler: Node library for creating custom protocol resolver; can be used as Express middleware.
const protocolHandler = require('custom-protocol-handler')(); protocolHandler.protocol('s3://', url => 'https://example.com'); // Standalone usage protocolHandler.resolve('s3://test').then(url => console.log(url)); //=> https://example.com // Using as Express middleware const port = 3000; const app = require('express')(); app.get('/resolve', protocolHandler.middleware()); app.listen(port, () => console.log('listening on port: %i!', port));
Author   vladimyr