<- Back to Blog

Deep Linking for Desktop Apps: Avoiding Browser Blocks

How to make deep linking work reliably in desktop apps by handling browser popup blockers

iason-p
Iason P. ·
Deep Linking for Desktop Apps: Avoiding Browser Blocks

TL;DR#

Problem: Browsers block automatic deep links to desktop apps because they're treated as unwanted popups. Solution: Always require a manual user click to trigger the deep link. Show a modal with a button instead of automatically redirecting.

Contents#

Desktop app deep linking#

Deep linking for desktop apps is when you want your app to open directly via a custom URI scheme (like myapp://), typically from a web page. This is commonly used in authentication flows where users complete OAuth on a web page and get redirected back to your desktop app.

In this post, I'll explain why deep linking doesn't always work as expected in browsers and how to make it work reliably every time.

This applies to all desktop app frameworks including Tauri, Electron, and native applications.

The problem#

Since we launched Hopp's waiting list, we had an annoying issue with our authentication flow: deep linking was not working with all browsers.

But he struggled with the auth token. He had to insert the auth token manually to log in.

Hopp's real user

This is how our sign-up flow looks:

Hopp's sign up flow
Hopp's sign up flow

In the above flow, the problem was the last step, where it was not working all the time and the browser was blocking the deep linking pop-up.

Example from Safari blocking the deep linking pop-up:

Safari error
Safari browser error message shown when deep linking fails

Why this is happening#

Modern browsers block deep linking requests that happen automatically because they're treated as popup attempts without explicit user interaction. This is a security feature to prevent websites from opening unwanted applications or windows without the user's consent.

Makes sense

The solution#

The solution is straightforward: always require manual user interaction. Instead of automatically triggering the deep link, show a modal dialog that prompts the user to click a button to open the app.

Yes, this adds one extra click, but it guarantees that deep linking works reliably across all browsers. The key insight is that browsers allow deep links when they're triggered by a direct user action (like clicking a button), but block them when they happen automatically.

const handleOpenHopp = () => {
   // ...
    try {
      window.open(`hopp:///authenticate?token=${appAuthToken}`, "_blank");
    } catch {
      toast.error("Could not open the app. Please try the manual copy option below.");
    }
};

<Button size="lg" onClick={handleOpenHopp}>
    Open Hopp
</Button>

The authentication flow went from this:

Old deep linking
Old authentication flow

to this:

New deep linking
New authentication flow

Conclusion#

The key takeaway is simple: browsers block automatic deep links, but allow user-initiated ones. When implementing deep linking for desktop apps, always show a confirmation dialog with a button rather than automatically redirecting. This ensures your deep linking works consistently across all browsers and provides a better user experience.

If you have any questions about implementing deep linking in your desktop app, feel free to reach out to me on X/Twitter or email me directly at iason at gethopp dot app.

desktop-apps
deep-linking
browser-security
GET STARTED

Ready for a better way to pair?

Imagine never losing your flow to screen sharing lag again. Picture pairing sessions that feel as smooth as coding locally. You're not just getting a tool—you're unlocking the collaboration experience that separates world-class developers from the rest.