Introduction to the Deep Link Plugin
Learn what deep links are, the real-world problems they solve, and how Tauri's deep link plugin enables your app to receive and react to custom URLs across all supported platforms.
A deep link is a special kind of URL that opens a specific screen or triggers a specific action inside an application, rather than just launching the app's home page. When a user clicks myapp://product/42, the operating system checks which apps can handle that scheme, picks yours, and hands it the full URL. Your application then decides what to do — show the product with ID 42, open a settings panel, or exchange an OAuth code for a session.
Deep links are not a separate technology from regular URLs. They are URLs that happen to be registered by an app instead of a browser. The Tauri deep link plugin gives your Tauri application the ability to register these URLs and respond to them, no matter which platform the user is on.
Why Deep Links Are Necessary
Without deep links, every external interaction — a password reset link in an email, an OAuth login flow, a "Pay Now" button on a website — would drop the user onto your app's main screen, leaving them to navigate manually. In many cases, that experience is broken: the OAuth flow expects a callback to a specific route, and if your app can't receive that callback, the login fails.
Deep links solve this by letting external sources (websites, emails, other apps) point directly to a destination inside your application. The OS acts as the delivery service: it routes the URL to the right app, and the app decides what to do with the path and query parameters.
This mechanism powers:
- OAuth and authentication callbacks — after a user authorizes in the browser, the provider redirects to a URL like
myapp://auth/callback?code=abc123. Your app catches that and exchanges the code for tokens. - Password reset and magic links — an email contains a link that opens the app and takes the user straight to the reset form.
- Cross-app communication — a companion mobile app or desktop tool sends data to your Tauri app via a URL.
- Deep-linking from marketing campaigns — a promotional email or QR code opens a specific feature or discount page.
Beginners sometimes think deep links are a web-only concept. In reality, native desktop and mobile apps have used them for years. The mechanics differ by platform, but the goal is the same: let the outside world talk to your app in a structured way.
How Deep Links Work Across Platforms
When a user clicks a link, the operating system looks at its list of registered URL handlers. Each handler declares which schemes and domains it can open. For example, a Tauri app might register the custom scheme myapp or claim ownership of https://mycompany.com/app.
Mobile Platforms
On Android and iOS, two patterns exist:
- Custom URI schemes (
myapp://...) — no server verification needed. The OS simply opens any URL with that scheme using the app that registered it. This is the simplest approach, but it is also the least secure because any app could register the same scheme. - App Links (Android) and Universal Links (iOS) (
https://yourdomain.com/...) — these require you to host a verification file on your server (.well-known/assetlinks.jsonfor Android,.well-known/apple-app-site-associationfor iOS). The OS checks that your website explicitly authorizes your app to handle those URLs. Only after verification will the OS route the link to your app instead of the browser. This is the preferred pattern for production apps because it prevents malicious apps from hijacking your links.
Verification Is Not Optional for HTTPS Links:
If you want your app to handle https://yourdomain.com/open/* on mobile, you must host the verification file on yourdomain.com. Without it, the OS will ignore your app's registration and open the link in the browser instead. This is the single most common reason deep links fail during initial setup.
Desktop Platforms
On macOS, deep links use Apple's event system. When a URL like myapp://something is triggered, macOS sends an "open URL" event to your running app or launches it and passes the URL. The plugin handles this event internally and forwards it to your JavaScript or Rust handlers.
On Windows and Linux, deep links are delivered as command-line arguments. The operating system starts a new instance of your application with the URL appended to the argument list. This has a significant implication: by default, every deep link click launches a fresh app process. To avoid multiple windows and instead handle the URL in the existing instance, you must combine the deep link plugin with the single-instance plugin.
Desktop Platform Differences:
The event-driven model on macOS, iOS, and Android means your app can listen for URLs while running. On Windows and Linux, the command-line model means you need the single-instance plugin to prevent duplicate processes and to forward the URL from the new instance to the already-running one. We'll cover this setup in detail later.
This platform diversity is precisely why the Tauri deep link plugin exists: it abstracts these differences behind a unified JavaScript and Rust API.
Common Use Cases for Deep Links
The same plugin API supports a wide range of real-world scenarios. Here are the most frequent ones you'll encounter when building a Tauri application.
OAuth and Third-Party Authentication
When you add "Sign in with Google," "Sign in with GitHub," or any OAuth provider to your Tauri app, the flow typically opens the user's browser. After the user authorizes, the provider redirects to a callback URL you specify. That callback must point back into your app. A custom scheme like myapp://auth/callback makes that possible.
The app receives the full URL, extracts the authorization code from the query string, and exchanges it for tokens. This is the same pattern used by countless desktop and mobile apps.
Magic Link and Password Reset
A backend service sends an email containing a link like myapp://reset-password?token=xyz. The user clicks it, the OS opens your app, and your app extracts the token to show the new-password form. Without deep links, the user would have to open the app, find the reset screen, and paste the token manually.
Payment Callbacks
Some payment providers (Stripe, PayPal, local payment gateways) redirect users back to a merchant app after completing or canceling a transaction. Your Tauri app handles a URL like myapp://payment/result?status=success&order=1234 and shows the appropriate confirmation or retry screen.
Custom URI Protocol for Companion Tools
If you build a suite of tools — a CLI, a web dashboard, and a desktop app — you can define a custom protocol like mytool://open-file?path=/home/user/doc.txt so that the CLI can tell the desktop app to open a specific file. This is common in developer tools and productivity applications.
Third-Party Service Integration
A local service running on the user's machine (like a hardware driver, a local server, or a game launcher) can communicate with your Tauri app by sending URLs. Your app becomes an endpoint for these local processes, much like a webhook but for the desktop.
You're on the Right Track If...:
If any of these scenarios match a feature you need in your application, then deep links are the correct pattern. Many production Tauri apps rely on this plugin for their authentication, inter-process communication, and notification flows.
Deep Links in Tauri
The @tauri-apps/plugin-deep-link plugin handles all platform-specific registration and event forwarding so you can write a single JavaScript (or Rust) function that receives URLs, regardless of whether your user is on macOS, Windows, Linux, Android, or iOS.
What the Plugin Does for You
- Registers URL schemes based on your
tauri.conf.jsonconfiguration. On mobile, it also handles the App Link / Universal Link verification setup. - Emits events (
deep-link://new-url) when a new URL arrives while the app is already running. On macOS, iOS, and Android, this event fires directly. On Windows and Linux, when combined with the single-instance plugin, the second instance forwards the URL and exits. - Provides a
getCurrent()function so you can check, on startup, whether the app was launched by a deep link. This covers the case where the app was completely closed and the OS launched it fresh with a URL. - Offers runtime registration (desktop only) for cases where you need to register custom schemes after installation, not just at build time.
Beginners can think of the plugin as a courier service. You tell it which addresses your app accepts (the URL schemes and hosts), and it makes sure every incoming package (URL) gets delivered to your handler function.
A First Look at the API
The JavaScript surface is deliberately small. A typical usage pattern from your React frontend looks like this:
import { getCurrent, onOpenUrl } from '@tauri-apps/plugin-deep-link';
// Check if the app was launched via a deep link
const urls = await getCurrent();
if (urls && urls.length > 0) {
console.log('App started with URL:', urls[0]);
}
// Listen for deep links while the app is running
await onOpenUrl((urls) => {
console.log('Received while running:', urls);
// Route based on the URL path and parameters
});
The same pattern works identically across all platforms, even though the underlying OS mechanisms are completely different. On desktop, you'll need the single-instance plugin for the onOpenUrl listener to work, but the frontend code itself does not change.
Security Considerations and Pitfalls
Deep links are a public interface to your application. Anyone can craft a URL with your registered scheme and attempt to trigger it, whether by sending a link in a chat message, hosting it on a website, or running a local script. This means you must never trust the raw URL content.
Never Trust Deep Link Parameters Blindly:
Parameters embedded in deep link URLs are user-controlled input, just like URL parameters in a web application. Do not use them directly in file paths, SQL queries, shell commands, or other sensitive operations without validation and sanitization. A maliciously crafted myapp://delete-file?path=../../../etc/passwd should never succeed.
The most common security mistake is treating deep link URLs as trusted because they come from "your" scheme. Schemes are not secrets. Any application on the system can attempt to open your scheme, and on mobile, another app could register the same custom scheme and intercept your links if you haven't used verified App Links / Universal Links.
Additional pitfalls to keep in mind:
- Using custom schemes for sensitive flows on mobile without migrating to verified HTTPS links. A rogue app can register the same custom scheme and steal OAuth tokens. Use App Links and Universal Links in production.
- Forgetting that deep links launch a new process on Windows and Linux. Without the single-instance plugin, each click opens a fresh window, and the URL may get lost if the original instance isn't aware. This leads to confusing behavior where "nothing happens."
- Assuming
onOpenUrlworks on desktop without configuration. On Windows and Linux, the event-driven listener only works when the single-instance plugin is active and correctly wired. The plugin's documentation makes this explicit, but many developers miss it during initial setup.
Beginners should treat deep link handling the same way they treat any network input: validate, sanitize, and only then act.
Summary
Deep links bridge the gap between the web and your desktop app. Treat them carefully as user input, and ensure proper OS-level registration.