Deeplink Testing
The service provides the ability to test custom protocol handlers and deeplinks in your Tauri application using the browser.tauri.triggerDeeplink() method.
Overviewโ
What is Deeplink Testing?โ
Deeplink testing allows you to verify that your Tauri application correctly handles custom protocol URLs (e.g., myapp://action?param=value). This is essential when your app registers as a protocol handler and needs to respond to URLs opened from external sources.
When Should You Use It?โ
Use browser.tauri.triggerDeeplink() when you need to:
- Test that your app correctly handles custom protocol URLs
- Verify deeplink parameter parsing and routing logic
- Test protocol handler registration and activation
- Validate deeplink-driven workflows in your application
Prerequisitesโ
Tauri Deep Link Pluginโ
Your Tauri app must have the @tauri-apps/plugin-deep-link plugin installed and configured. See the official Tauri deep linking documentation for setup instructions.
Protocol Registrationโ
Your app must register its custom protocol scheme in tauri.conf.json under the deep-link plugin configuration:
{
"plugins": {
"deep-link": {
"desktop": {
"schemes": ["myapp"]
}
}
}
}
Basic Usageโ
Simple Exampleโ
describe('Protocol Handler Tests', () => {
it('should handle custom protocol deeplinks', async () => {
await browser.tauri.triggerDeeplink('myapp://open?file=test.txt');
await browser.waitUntil(async () => {
const openedFile = await browser.tauri.execute(() => {
return globalThis.lastOpenedFile;
});
return openedFile === 'test.txt';
}, {
timeout: 5000,
timeoutMsg: 'App did not handle the deeplink'
});
});
});
Complex URL Parametersโ
it('should preserve query parameters', async () => {
await browser.tauri.triggerDeeplink(
'myapp://action?param1=value1¶m2=value2&array[]=a&array[]=b'
);
const receivedParams = await browser.tauri.execute(() => {
return globalThis.lastDeeplinkParams;
});
expect(receivedParams.param1).toBe('value1');
expect(receivedParams.param2).toBe('value2');
expect(receivedParams.array).toEqual(['a', 'b']);
});
Error Handlingโ
it('should reject invalid protocols', async () => {
await expect(
browser.tauri.triggerDeeplink('https://example.com')
).rejects.toThrow('Invalid deeplink protocol');
});
it('should reject malformed URLs', async () => {
await expect(
browser.tauri.triggerDeeplink('not a url')
).rejects.toThrow('Invalid deeplink URL');
});
Platform Behaviorโ
The service handles platform-specific differences automatically:
Windowsโ
- Uses
cmd /c startcommand to trigger the deeplink - No URL modification needed
macOSโ
- Uses
opencommand to trigger the deeplink - No URL modification needed
Linuxโ
- Uses
xdg-opencommand to trigger the deeplink - No URL modification needed
App Implementationโ
Frontend Deep Link Listenerโ
Your app needs to listen for deep links in the frontend:
import { listen } from '@tauri-apps/plugin-deep-link';
listen('myapp://', (url) => {
console.log('Received deeplink:', url);
const parsed = new URL(url);
globalThis.lastDeeplinkUrl = url.toString();
const action = parsed.hostname;
const params = Object.fromEntries(parsed.searchParams);
switch (action) {
case 'open':
if (params.file) {
globalThis.lastOpenedFile = params.file;
}
break;
case 'action':
globalThis.lastDeeplinkParams = params;
break;
}
});
Backend Handler (Optional)โ
For more complex scenarios, you can also handle deep links in the Rust backend:
use tauri_plugin_deep_link::DeepLinkExt;
#[tauri::main]
async fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_deep_link::init())
.setup(|app| {
app.handle().register_uri_scheme_protocol("myapp", |request| {
let url = request.url();
println!("Received deep link: {}", url);
});
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Common Issuesโ
Deeplinks Not Received in Appโ
Symptom: The deeplink is triggered but your app doesn't receive it.
Possible Causes and Solutions:
-
Protocol not registered:
- Verify
protocol.registeris set intauri.conf.json - Check your app is properly registered as the handler
- Verify
-
Deep link listener not set up:
- Ensure
listen()from@tauri-apps/plugin-deep-linkis called - Verify the listener is set up before triggering the deeplink
- Ensure
-
Deep link parsed incorrectly:
- Check console logs to see if the URL is being received
- Verify URL parsing logic handles your URL format
Invalid Deeplink Protocol Errorโ
Symptom: Error: "Invalid deeplink protocol: https. Expected a custom protocol."
Cause: You're trying to use triggerDeeplink() with http/https/file protocols.
Solution: Only use custom protocol schemes:
// Correct - custom protocol
await browser.tauri.triggerDeeplink('myapp://action');
// Incorrect - web protocol
await browser.tauri.triggerDeeplink('https://example.com'); // Throws error
// Incorrect - file protocol
await browser.tauri.triggerDeeplink('file:///path/to/file'); // Throws error
Timing Issuesโ
Symptom: Tests fail intermittently because the app hasn't processed the deeplink yet.
Solution: Always use waitUntil to wait for the app to process the deeplink:
await browser.tauri.triggerDeeplink('myapp://action');
await browser.waitUntil(async () => {
const processed = await browser.tauri.execute(() => {
return globalThis.deeplinkProcessed;
});
return processed === true;
}, {
timeout: 5000,
timeoutMsg: 'App did not process the deeplink within 5 seconds'
});
See Alsoโ
- Tauri Deep Linking Documentation
- API Reference for complete method documentation
- Usage Examples for additional patterns