🚧 Glyx is pre-release software. APIs may change before v1.0. Get started →
Documentation
APIs & Bindings
deeplink

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:

glyx.config.json
{
  "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:

  1. Immediately (on first onOpen call) with the launch URL if the app was opened via a link.
  2. 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.