🚧 VeloxKit 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

veloxkit.config.json
{
  "capabilities": ["deeplink"]
}

Configure your URL scheme

veloxkit.config.json
{
  "deeplink": {
    "scheme": "myapp"
  }
}

This registers myapp:// on Windows (registry), macOS (Info.plist), and Linux (.desktop file) when the app is installed.

Import

import { deeplink } from 'veloxkit'

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 'veloxkit'
import { useNavigate } from 'veloxkit/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 'veloxkit'
 
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 fetch(authUrl)  // or use a shell open command via backend.*
 
  // 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)
  }
})

VeloxKit enforces single-instance by default. If the user clicks a link while the app is already running, the URL is forwarded to the running instance via the onOpen callback — a second process is never spawned.