Skip to content

Tauri (Rust + webview) example — direct + deferred deep links via a mobile plugin #12

Open

Description

@joeblew999

I'm building a Tauri 2 app that ships to desktop and mobile from one webview, and I'd like to integrate against your mobile-v1 contract rather than a proprietary SDK. Would you be open to a Tauri reference in this repo? If so I'm happy to build and PR it.

Why Tauri

Tauri 2 is the main Rust-based webview path for mobile, and there's no clean reference for deferred deep links in that ecosystem. Tauri already has tauri-plugin-deep-link for the installed case (Universal Links / App Links), but nothing covers the install gap.

Proposed shape

Closer to your React Native / Flutter native-adapter pattern than a full fifth app:

  • tauri-plugin-zq-deferred — a Tauri mobile plugin
    • Android (Kotlin): reads Google Play Install Referrer on first launch, persists it, exposes it via a command
    • iOS (Swift): exposes a UIPasteControl so recovery is an explicit user action; no pasteboard read at launch
  • JS consumer — resolves the URL through the contract endpoints and posts the signed route_ack receipt only after the destination route opens
  • validate.sh hook — non-interactive checks with ZQ_* output prefixes, matching the existing harness

It would reuse tauri-plugin-deep-link for direct links so both paths feed the same route handler. Same constraints as the other examples: no fingerprinting, no advertising IDs, receipts are never manufactured client-side.

Questions

  1. Would you accept this as a tauri/ directory alongside the others, or would you prefer it live in a separate repo you link to?
  2. Anything in the contract you'd want a webview-based host to handle differently from the native examples (e.g. app-bound receipt verification when the webview origin is a local scheme)?

If the answer is yes I'll open a draft PR once the plugin passes validate.sh.

Two clarifications on scope:

Desktop. The same Tauri app also ships to macOS/Windows/Linux, and the install gap exists there too. I'd cover it behind the same getPendingRoute() surface — clipboard read on explicit tap on desktop, a remy:// probe-with-fallback on the landing page, and single-instance routing. That raises a contract question: mobile-v1 binds receipts to a store-verified app identity, which desktop builds don't have. Would you prefer desktop acks be out of scope, a lower-trust tier, or is a desktop identity something you'd consider adding?

Demo shape. It'd be a small Tauri app rather than a plugin alone, mirroring your React Native / Flutter layout:

  • tauri/app/ — one webview frontend with two screens (pending route → route opened), calling getPendingRoute() on first launch and posting route_ack after the destination renders
  • tauri/plugins/deferred-link/ — the plugin (Rust core + Kotlin / Swift / desktop backends), consumed by path
  • tauri/landing/ — a static landing page: scheme probe, store/download fallback, token-to-clipboard on click. Your other examples don't need this; a webview app does
  • platform config with placeholder hosts, same caveat as your README

Desktop builds run headless in CI, so the Tauri example could be the one that validates end-to-end rather than structurally.

Activity

  1. ZipQuantumHQ commented on Sep 11, 2026

    @ZipQuantumHQ
    Collaborator

    Thanks for the detailed proposal. Yes, we’d be open to reviewing this as a tauri/ directory alongside the existing examples. Keeping it here makes the contract, validation harness, and security invariants easier to review together.

    A few scope boundaries for the first draft:

    • Mobile direct and deferred delivery can target the existing mobile-v1 contract.
    • Desktop direct-link and single-instance handling can be demonstrated in the same example.
    • Desktop deferred recovery may be included locally, but desktop route_ack should remain out of scope until a separate trust contract exists. Please don’t invent a desktop identity or lower-trust receipt under mobile-v1.
    • The webview’s local origin is not an application identity. On mobile, the client should forward the server-issued opaque receipt only after the destination renders, using the registered platform identifier required by the contract. It must never manufacture, decode, sign, persist, print, or replay the receipt.
    • Keep hosts and identifiers as placeholders, with no live tokens, keys, certificates or receipts.
    • Please register the Tauri single-instance plugin before the deep-link plugin and cover both initial-launch and already-running delivery.
    • The draft PR should include the app, plugin, focused documentation and deterministic validation using the existing ZQ_* output conventions.

    A draft PR under tauri/ is the right next step. Review and final inclusion would remain subject to the repository’s tests and normal review.

  2. ZipQuantumHQ commented on Sep 14, 2026

    @ZipQuantumHQ
    Collaborator

    A small acceptance checklist for the first draft, so it can stay intentionally narrow:

    • Cold-start delivery and an already-running second instance feed the same allowlisted route parser; the single-instance plugin is registered first.
    • Mobile getPendingRoute() is one-shot and never logs or persists the full recovered URL or opaque receipt.
    • route_ack is emitted only by the mobile path, after the destination renders. Desktop demonstrates direct-link/single-instance routing only and emits no ack.
    • The validator covers direct cold start, direct warm delivery, deferred mobile recovery, replay/second read, and unknown routes with deterministic ZQ_* PASS/FAIL output and placeholder identifiers only.

    If you're still planning the contribution, a draft PR that proves those gates is enough for the first review; packaging and broader desktop recovery can remain follow-up work.

  3. ZipQuantumHQ commented on Sep 14, 2026

    @ZipQuantumHQ
    Collaborator

    @joeblew999 Thanks again for proposing this. We went ahead and built the reference integration, reviewed it, and merged it in #13; all 12/12 checks passed.

    The merged example covers mobile-v1 direct and deferred delivery, Android Play Install Referrer, iOS UIPasteControl, desktop direct links with single-instance registered first, and the same route path for cold and warm delivery. Mobile route_ack is sent only after the destination renders; desktop route_ack remains intentionally out of scope. The hosts and app identifiers are placeholders to replace in a real deployment.

    Appreciate the push—your proposal helped define the shape of the example.

    Implementation guide and architecture notes: Tauri Deep Links: A Tested iOS, Android and Desktop Reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions