deeplink Stable WINMACLNX
Register a custom URL scheme so the OS can launch (or focus) your app and pass a URL — useful for OAuth callbacks, inter-app communication, and universal links.
Capability
deeplink is declared as an object under capabilities, not a separate
top-level key — it carries the scheme and single-instance config together:
{
"capabilities": {
"deeplink": {
"scheme": "myapp",
"singleInstance": true
}
}
}This registers myapp:// on Windows (registry), macOS (Info.plist), and Linux (.desktop file) when the app is installed.
singleInstance defaults to false. Without setting it explicitly,
a second link click launches a brand-new process instead of forwarding
the URL to the already-running app — the OAuth-callback pattern below
requires singleInstance: true to work at all.
Import
import { deeplink } from '@glyx-dev/react'deeplink.onOpen(callback)
Register a callback for every incoming deep-link URL, including the URL that launched this instance of the app.
The callback fires:
- Immediately (on first
onOpencall) with the launch URL if the app was opened via a link. - Each time the OS sends a new URL to the already-running app (single-instance forwarding).
const unsub = deeplink.onOpen((url) => {
console.log('deep link received:', url)
// e.g. 'myapp://note/42'
// e.g. 'myapp://oauth/callback?code=abc123'
})
// Cleanup:
useEffect(() => unsub, [])Returns an unsubscribe function.
Examples
Navigate to content from a URL
import { deeplink } from '@glyx-dev/react'
import { useNavigate } from 'glyx/router'
import { useEffect } from 'react'
function App() {
const navigate = useNavigate()
useEffect(() => {
return deeplink.onOpen((url) => {
try {
const parsed = new URL(url)
// myapp://note/42 → { host: 'note', pathname: '/42' }
const [, resource, id] = parsed.pathname.split('/')
if (parsed.host === 'note' && id) {
navigate(`/notes/${id}`)
} else if (parsed.host === 'settings') {
navigate('/settings')
}
} catch {
// ignore malformed URLs
}
})
}, [navigate])
// ...
}OAuth callback flow
import { deeplink } from '@glyx-dev/react'
async function startOAuthLogin() {
// Open browser for OAuth
const authUrl = 'https://accounts.example.com/oauth/authorize'
+ `?client_id=MY_CLIENT_ID`
+ `&redirect_uri=${encodeURIComponent('myapp://oauth/callback')}`
+ `&response_type=code`
// Open in default OS browser
await glyxWindow.openExternal(authUrl) // opens in the OS default browser
// Wait for the callback
return new Promise<string>((resolve, reject) => {
const unsub = deeplink.onOpen((url) => {
if (!url.startsWith('myapp://oauth/callback')) return
const code = new URL(url).searchParams.get('code')
if (code) { unsub(); resolve(code) }
else { unsub(); reject(new Error('No code in callback')) }
})
// Timeout after 5 minutes
setTimeout(() => { unsub(); reject(new Error('OAuth timeout')) }, 5 * 60 * 1000)
})
}Share target (receive content from other apps)
// Another app opens: myapp://import?url=https%3A%2F%2Fexample.com
deeplink.onOpen((url) => {
if (url.startsWith('myapp://import')) {
const targetUrl = new URL(url).searchParams.get('url')
if (targetUrl) importUrl(targetUrl)
}
})Single-instance forwarding is opt-in, not the default — set
singleInstance: true (see Capability above). With it set,
clicking a link while the app is already running forwards the URL to the
running instance via onOpen instead of spawning a second process.
Without it, every link click launches a new process.
Forwarding only delivers the URL — it does not bring the existing window
to the foreground. There's currently no JS API to force-focus the window;
the closest available workaround is glyxWindow.setMinimized(false) from
your onOpen handler, which un-minimizes but doesn't guarantee raising
above other windows on every OS. A real "bring to front" primitive is a
known gap, not yet built.