| name | electron-protocol-handler-setup |
| description | Register and handle custom URL protocols (deep linking) across platforms for Electron applications |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep |
| tags | ["electron","deep-linking","protocol-handler","url-scheme","desktop"] |
| graph | {"domains":["domain:software-engineering"],"specializations":["specialization:desktop-development"],"skillAreas":["skill-area:desktop-ui-frameworks","skill-area:cross-platform-desktop","skill-area:protocol-design"],"roles":["role:desktop-developer","role:fullstack-engineer"],"workflows":["workflow:feature-development","workflow:release-management"]} |
electron-protocol-handler-setup
Register and handle custom URL protocols (deep linking) for Electron applications across Windows, macOS, and Linux. This skill enables apps to respond to custom URL schemes like myapp:// for deep linking and inter-application communication.
Capabilities
- Register custom protocol handlers at OS level
- Handle protocol URLs in running application
- Configure electron-builder for protocol registration
- Implement secure URL parsing and validation
- Handle protocol activation on app launch
- Support single-instance enforcement with protocol handling
- Generate platform-specific registration scripts
- Test protocol handling in development
Input Schema
{
"type": "object",
"properties": {
"projectPath": {
"type": "string",
"description": "Path to the Electron project root"
},
"protocols": {
"type": "array",
"items": {
"type": "object",
"properties": {
"scheme": { "type": "string", "description": "Protocol scheme (e.g., 'myapp')" },
"name": { "type": "string", "description"
Output Schema
{
"type": "object",
"properties": {
"success": { "type": "boolean" },
"files": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": { "type": "string" },
"description": { "type": "string" }
}
}
},
"configuration": {
"type": "object"
Platform Registration
macOS (Info.plist)
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>My App Protocol</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
Windows (Registry)
nsis:
perMachine: true
include: "installer.nsh"
; installer.nsh
!macro customInstall
WriteRegStr HKCU "Software\Classes\myapp" "" "URL:My App Protocol"
WriteRegStr HKCU "Software\Classes\myapp" "URL Protocol" ""
WriteRegStr HKCU "Software\Classes\myapp\shell\open\command" "" '"$INSTDIR\MyApp.exe" "%1"'
!macroend
Linux (Desktop Entry)
[Desktop Entry]
Name=My App
Exec=/opt/myapp/myapp %u
Type=Application
MimeType=x-scheme-handler/myapp
Implementation
Protocol Handler Class
const { app, shell } = require('electron');
const url = require('url');
class ProtocolHandler {
constructor(mainWindow, options = {}) {
this.mainWindow = mainWindow;
this.scheme = options.scheme || 'myapp';
this.allowedHosts = options.allowedHosts || [];
this.handlers = new Map();
}
register() {
if (process.defaultApp) {
app.setAsDefaultProtocolClient(this.scheme, process.execPath, [
path.resolve(process.argv[1])
]);
} else {
app.setAsDefaultProtocolClient(this.scheme);
}
}
unregister() {
app.removeAsDefaultProtocolClient(this.scheme);
}
() {
(!.(protocolUrl)) {
.(, protocolUrl);
;
}
parsed = url.(protocolUrl, );
route = parsed. || parsed.?.();
params = parsed.;
handler = ..(route);
(handler) {
(params, parsed);
} {
.(, route);
}
(.) {
(..()) {
..();
}
..();
}
}
() {
{
parsed = url.(protocolUrl);
(parsed. !== ) {
;
}
(.. > && parsed.) {
(!..(parsed.)) {
;
}
}
;
} {
;
}
}
() {
..(route, handler);
}
}
. = ;
Main Process Integration
const { app } = require('electron');
const ProtocolHandler = require('./protocol-handler');
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
} else {
let mainWindow;
let protocolHandler;
app.on('second-instance', (event, commandLine) => {
const url = commandLine.find(arg => arg.startsWith('myapp://'));
if (url) {
protocolHandler.handleUrl(url);
}
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
}
});
app.on('open-url', (event, url) => {
event.preventDefault();
if (protocolHandler) {
protocolHandler.handleUrl(url);
}
});
app.whenReady().( {
mainWindow = ();
protocolHandler = (mainWindow, {
: ,
: [, , ]
});
protocolHandler.();
protocolHandler.(, {
mainWindow..(, params);
});
protocolHandler.(, {
(params);
});
launchUrl = process..( arg.());
(launchUrl) {
protocolHandler.(launchUrl);
}
});
}
electron-builder Configuration
protocols:
- name: "My App Protocol"
schemes:
- myapp
role: Viewer
mac:
extendInfo:
CFBundleURLTypes:
- CFBundleURLName: "My App Protocol"
CFBundleURLSchemes:
- myapp
linux:
mimeTypes:
- x-scheme-handler/myapp
desktop:
MimeType: "x-scheme-handler/myapp;"
Security Considerations
- Validate all URLs: Never trust protocol URL content
- Whitelist routes: Only handle known routes
- Sanitize parameters: Clean query parameters before use
- Avoid code execution: Never eval protocol URL content
- Log suspicious URLs: Track invalid protocol attempts
validateParams(params) {
const sanitized = {};
const allowedParams = ['id', 'action', 'token'];
for (const [key, value] of Object.entries(params)) {
if (allowedParams.includes(key)) {
sanitized[key] = String(value).slice(0, 1000);
}
}
return sanitized;
}
Testing
open "myapp://open?file=test.txt"
start "" "myapp://open?file=test.txt"
xdg-open "myapp://open?file=test.txt"
Related Skills
electron-ipc-security-audit - Secure protocol handling
inter-app-communication process - IPC patterns
electron-builder-config - Package protocol handlers
Related Agents
electron-architect - Architecture guidance
desktop-security-auditor - Security review