{"id":1289,"date":"2026-06-01T17:00:00","date_gmt":"2026-06-01T22:00:00","guid":{"rendered":"https:\/\/tolinku.com\/blog\/?p=1289"},"modified":"2026-03-07T03:49:05","modified_gmt":"2026-03-07T08:49:05","slug":"clipboard-based-deferred-linking","status":"publish","type":"post","link":"https:\/\/tolinku.com\/blog\/clipboard-based-deferred-linking\/","title":{"rendered":"Clipboard-Based Deferred Deep Linking: How It Works"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Deferred deep linking bridges the gap between a link click and an app install. When a user taps a link, installs the app, then opens it for the first time, deferred deep linking routes them to the right content. The challenge is preserving that link context across the install. Traditional approaches use fingerprinting (matching device attributes) or deterministic identifiers, but both have limitations: fingerprinting is probabilistic and increasingly restricted by privacy regulations, while deterministic matching requires platform-specific APIs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Clipboard-based deferred linking is a third approach. It copies a token to the device clipboard when the user clicks the link, then reads it back when the app opens. It is deterministic (100% match accuracy when it works), requires no device fingerprinting, and works across platforms. But it comes with its own set of tradeoffs, particularly on iOS where paste permissions have become increasingly restrictive.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the fundamentals of deferred deep linking, see <a href=\"https:\/\/tolinku.com\/blog\/deferred-deep-linking-how-it-works\/\">how deferred deep linking works<\/a>. For a comparison of matching techniques, see <a href=\"https:\/\/tolinku.com\/blog\/fingerprinting-vs-deterministic-matching\/\">fingerprinting vs. deterministic matching<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How Clipboard-Based Deferred Linking Works<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The flow is straightforward:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>User taps a link<\/strong> on the web (e.g., <code>https:\/\/yourapp.com\/invite\/abc123<\/code>).<\/li>\n<li><strong>The landing page copies a token to the clipboard.<\/strong> JavaScript writes a short identifier (the deep link context) to the system clipboard using the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Clipboard_API\" rel=\"nofollow noopener\" target=\"_blank\">Clipboard API<\/a>.<\/li>\n<li><strong>User installs the app<\/strong> from the App Store or Google Play.<\/li>\n<li><strong>App launches and reads the clipboard.<\/strong> On first open, the app checks the clipboard for a matching token.<\/li>\n<li><strong>App routes the user<\/strong> to the correct content based on the token.<\/li>\n<\/ol>\n\n\n\n<pre><code>Web page (click) \u2192 Copy token to clipboard \u2192 App Store \u2192 Install \u2192 App reads clipboard \u2192 Route user\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The token is typically a short string or URL that encodes the deep link destination and any attribution data (campaign ID, referrer, etc.). Some implementations copy the full URL; others copy a compact token that the app resolves via an API call.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Web Side: Copying to Clipboard<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Using the Clipboard API<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Modern browsers support the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Clipboard\/writeText\" rel=\"nofollow noopener\" target=\"_blank\">Clipboard API<\/a> for programmatic clipboard access:<\/p>\n\n\n\n<pre><code class=\"language-javascript\">async function copyDeferredLinkToken(token) {\n  try {\n    await navigator.clipboard.writeText(token);\n  } catch (err) {\n    \/\/ Fallback for browsers that block clipboard access\n    fallbackCopy(token);\n  }\n}\n\nfunction fallbackCopy(token) {\n  const textarea = document.createElement(&#39;textarea&#39;);\n  textarea.value = token;\n  textarea.style.position = &#39;fixed&#39;;\n  textarea.style.opacity = &#39;0&#39;;\n  document.body.appendChild(textarea);\n  textarea.select();\n  document.execCommand(&#39;copy&#39;);\n  document.body.removeChild(textarea);\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">When to Copy<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The copy should happen in response to a user gesture (tap or click). Browsers restrict clipboard write access to user-initiated events. Attempting to write to the clipboard without a user gesture fails silently or throws an error in most browsers.<\/p>\n\n\n\n<pre><code class=\"language-javascript\">document.getElementById(&#39;install-button&#39;).addEventListener(&#39;click&#39;, async () =&gt; {\n  \/\/ Copy the deferred link token\n  await copyDeferredLinkToken(&#39;dl_invite_abc123_campaign_summer2026&#39;);\n\n  \/\/ Redirect to the app store\n  window.location.href = &#39;https:\/\/apps.apple.com\/app\/yourapp\/id123456789&#39;;\n});\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This approach is transparent: the user clicked a button to install the app. The clipboard write happens as part of that action. Some implementations also show a brief toast (&quot;Link copied&quot;) to acknowledge the clipboard write.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Token Format<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Keep the token compact and identifiable. The app needs to distinguish your deferred link token from whatever else might be on the clipboard:<\/p>\n\n\n\n<pre><code class=\"language-javascript\">\/\/ Option 1: Prefixed token\nconst token = `tolinku:\/\/dl\/invite\/abc123?ref=campaign_summer`;\n\n\/\/ Option 2: JSON payload\nconst token = JSON.stringify({\n  _dl: true,\n  path: &#39;\/invite\/abc123&#39;,\n  ref: &#39;campaign_summer&#39;,\n  ts: Date.now()\n});\n\n\/\/ Option 3: Short URL\nconst token = &#39;https:\/\/tolk.link\/abc123&#39;;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Including a timestamp lets the app discard stale tokens (e.g., ignore anything older than 24 hours).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The App Side: Reading the Clipboard<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Android<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Android has no clipboard permission requirement. Apps can read the clipboard freely, though Android 12+ shows a toast notification (&quot;App pasted from your clipboard&quot;) when an app reads clipboard content.<\/p>\n\n\n\n<pre><code class=\"language-kotlin\">fun checkClipboardForDeferredLink(context: Context): String? {\n    val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager\n\n    if (!clipboard.hasPrimaryClip()) return null\n\n    val clip = clipboard.primaryClip ?: return null\n    val item = clip.getItemAt(0)\n    val text = item.text?.toString() ?: return null\n\n    \/\/ Check if it matches our deferred link format\n    if (text.startsWith(&quot;tolinku:\/\/dl\/&quot;) || text.startsWith(&quot;https:\/\/tolk.link\/&quot;)) {\n        \/\/ Clear the clipboard after reading\n        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.P) {\n            clipboard.clearPrimaryClip()\n        }\n        return text\n    }\n\n    return null\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On Android 12+ (API 31), the system toast notification is automatic and cannot be suppressed. Users see &quot;YourApp pasted from your clipboard&quot; briefly. On Android 13+ (API 33), the clipboard is automatically cleared after a period of time (approximately one hour) for privacy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">iOS: The Paste Permission Challenge<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">iOS is where clipboard-based deferred linking gets complicated. Apple has progressively tightened clipboard access:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>iOS 14+:<\/strong> Apps that read the clipboard trigger a banner notification: &quot;[App] pasted from [Source App].&quot; This banner is visible to the user and cannot be suppressed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>iOS 16+:<\/strong> Apple introduced the <a href=\"https:\/\/developer.apple.com\/documentation\/uikit\/uipastecontrol\" rel=\"nofollow noopener\" target=\"_blank\">UIPasteControl<\/a>, a system-provided button that grants clipboard access only when the user explicitly taps it. Direct programmatic access to <code>UIPasteboard<\/code> without user interaction now triggers a system permission dialog.<\/p>\n\n\n\n<pre><code class=\"language-swift\">\/\/ iOS 16+: Reading clipboard triggers a permission prompt\nfunc checkClipboardForDeferredLink() -&gt; String? {\n    let pasteboard = UIPasteboard.general\n\n    \/\/ This triggers a system prompt: &quot;[App] would like to paste from [Source]&quot;\n    guard let text = pasteboard.string else { return nil }\n\n    \/\/ Check for our token format\n    if text.hasPrefix(&quot;tolinku:\/\/dl\/&quot;) || text.hasPrefix(&quot;https:\/\/tolk.link\/&quot;) {\n        pasteboard.string = &quot;&quot; \/\/ Clear after reading\n        return text\n    }\n\n    return nil\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The system prompt asks the user to allow or deny the paste. If they deny, the app gets no clipboard data.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">iOS UX Patterns for Clipboard Access<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Because iOS now requires explicit user consent for clipboard access, you need a UX pattern that explains why the app wants to read the clipboard:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pattern 1: Contextual prompt before reading<\/strong><\/p>\n\n\n\n<pre><code class=\"language-swift\">func handleFirstLaunch() {\n    \/\/ Show an in-app explanation before triggering the system prompt\n    let alert = UIAlertController(\n        title: &quot;Complete Your Setup&quot;,\n        message: &quot;We detected you came from a shared link. Allow paste access to take you to the right place.&quot;,\n        preferredStyle: .alert\n    )\n    alert.addAction(UIAlertAction(title: &quot;Continue&quot;, style: .default) { _ in\n        if let token = self.checkClipboardForDeferredLink() {\n            self.routeToContent(token)\n        }\n    })\n    alert.addAction(UIAlertAction(title: &quot;Skip&quot;, style: .cancel))\n    present(alert, animated: true)\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pattern 2: UIPasteControl (iOS 16+)<\/strong><\/p>\n\n\n\n<pre><code class=\"language-swift\">\/\/ Add a UIPasteControl to your onboarding screen\nlet pasteConfig = UIPasteControl.Configuration()\npasteConfig.displayMode = .labelOnly\npasteConfig.cornerStyle = .capsule\n\nlet pasteControl = UIPasteControl(configuration: pasteConfig)\npasteControl.target = self\n\/\/ When user taps this system-provided button, clipboard access is granted without the prompt\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>UIPasteControl<\/code> is a system-rendered button that the user must tap. It bypasses the permission prompt because the tap itself constitutes explicit consent. The downside: you cannot customize its appearance beyond basic configuration, and you need to integrate it into your onboarding flow.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Privacy Considerations<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Clipboard-based deferred linking has a better privacy profile than fingerprinting in some respects, but it introduces its own concerns.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Advantages Over Fingerprinting<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>No device attribute collection.<\/strong> Fingerprinting collects IP address, screen resolution, OS version, browser user agent, language, timezone, and more. Clipboard-based linking collects none of these.<\/li>\n<li><strong>Deterministic matching.<\/strong> The token is either present or it is not. There are no false positives from coincidental fingerprint matches.<\/li>\n<li><strong>User visible.<\/strong> The clipboard operation is surfaced to the user via system UI (paste banners on iOS 14+, toast on Android 12+). Fingerprinting happens invisibly.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Concerns<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Clipboard contains sensitive data.<\/strong> Users copy passwords, addresses, private messages, and other sensitive content. An app that reads the clipboard is accessing whatever the user last copied, even if only to check for a deferred link token. This is why Apple added the paste permission.<\/li>\n<li><strong>Token persistence.<\/strong> The token stays on the clipboard until the user copies something else. If the user does not install the app immediately, the token might be overwritten. If they do install days later and the token is still there, the deferred link resolves with stale context.<\/li>\n<li><strong>Cross-app data leakage.<\/strong> Before iOS 14&#39;s paste notification, apps could silently read the clipboard on every launch. This led to <a href=\"https:\/\/arstechnica.com\/gadgets\/2020\/06\/tiktok-and-53-other-ios-apps-still-snoop-your-sensitive-clipboard-data\/\" rel=\"nofollow noopener\" target=\"_blank\">concerns about TikTok and other apps<\/a> reading clipboard data. Apple&#39;s paste notification was a direct response to this abuse.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For a broader discussion of privacy in deferred linking, see <a href=\"https:\/\/tolinku.com\/blog\/deferred-linking-privacy-considerations\/\">deferred linking privacy considerations<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reliability and Limitations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">When Clipboard Linking Fails<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>User copies something else.<\/strong> If the user copies text between clicking the link and opening the app, the token is gone.<\/li>\n<li><strong>Clipboard cleared by system.<\/strong> Android 13+ clears the clipboard after approximately one hour. iOS does not auto-clear, but apps like password managers may clear the clipboard after a timeout.<\/li>\n<li><strong>User denies paste permission (iOS 16+).<\/strong> The app cannot read the clipboard.<\/li>\n<li><strong>Browser blocks clipboard write.<\/strong> Some browsers restrict <code>navigator.clipboard.writeText()<\/code> even on user gestures if the page is not served over HTTPS or lacks <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Reference\/Headers\/Permissions-Policy\" rel=\"nofollow noopener\" target=\"_blank\">Permissions-Policy<\/a> headers.<\/li>\n<li><strong>In-app browsers.<\/strong> Social media in-app browsers (Instagram, Facebook, Twitter) may have different clipboard policies.<\/li>\n<li><strong>Token format collision.<\/strong> If the user happens to have text on their clipboard that matches your token format, the app may incorrectly interpret it as a deferred link.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Match Rates<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Clipboard-based deferred linking typically achieves 60-80% match rates in practice:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>100% when the token is present and the app can read it.<\/li>\n<li>Drops due to users copying other content before installing.<\/li>\n<li>Drops further on iOS 16+ due to paste permission denial.<\/li>\n<li>Time-to-install is the biggest factor. Immediate installs have near-100% match rates. Installs hours or days later drop significantly.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Compare this to fingerprinting (typically 50-70% accuracy) and deterministic matching via platform APIs like <a href=\"https:\/\/developer.android.com\/google\/play\/installreferrer\" rel=\"nofollow noopener\" target=\"_blank\">Google Play Install Referrer<\/a> (near-100% on Android).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Combining Approaches<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Most production deferred linking implementations do not rely on a single technique. They combine multiple methods and use the best available match:<\/p>\n\n\n\n<pre><code>1. Check Google Play Install Referrer (Android) \u2192 deterministic, highest confidence\n2. Check clipboard for token \u2192 deterministic, high confidence\n3. Check server-side fingerprint match \u2192 probabilistic, medium confidence\n4. Fall back to default onboarding \u2192 no match\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On iOS, the hierarchy might be:<\/p>\n\n\n\n<pre><code>1. Check clipboard (with paste permission) \u2192 deterministic\n2. Check SKAdNetwork \/ App Store attribution \u2192 limited data\n3. Check server-side fingerprint match \u2192 probabilistic\n4. Fall back to default onboarding \u2192 no match\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The clipboard check slots in as a high-confidence method that works when the token is available, with fingerprinting as a fallback for cases where the clipboard was overwritten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Tolinku&#39;s Approach<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/tolinku.com\/features\/deep-linking\">Tolinku&#39;s deferred deep linking<\/a> uses a combination of techniques to maximize match rates while respecting user privacy. When a user clicks a Tolinku link and installs the app, the SDK attempts multiple matching strategies in order of confidence. Clipboard matching is one component of this pipeline, not the sole mechanism.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Configure your deferred deep linking settings in the <a href=\"https:\/\/tolinku.com\/docs\/concepts\/deferred-deep-linking\/\">Tolinku dashboard<\/a>. The SDK handles the clipboard read, permission flow (on iOS), and fallback logic automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For more on deferred deep linking accuracy across methods, see <a href=\"https:\/\/tolinku.com\/blog\/deferred-linking-accuracy\/\">deferred linking accuracy<\/a>. For the full deferred deep linking overview, see <a href=\"https:\/\/tolinku.com\/blog\/deferred-deep-linking-how-it-works\/\">how deferred deep linking works<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Explore clipboard-based deferred deep linking as a privacy-friendly alternative to fingerprinting. Learn iOS paste permissions, UX patterns, and implementation details.<\/p>\n","protected":false},"author":2,"featured_media":1288,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Clipboard-Based Deferred Deep Linking: How It Works","rank_math_description":"Explore clipboard-based deferred deep linking as a privacy-friendly alternative to fingerprinting. Learn iOS paste permissions and UX patterns.","rank_math_focus_keyword":"clipboard deferred deep linking","rank_math_canonical_url":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-clipboard-based-deferred-linking.png","rank_math_facebook_image_id":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-clipboard-based-deferred-linking.png","footnotes":""},"categories":[11],"tags":[329,20,21,24,69,330,36,33],"class_list":["post-1289","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deep-linking","tag-clipboard","tag-deep-linking","tag-deferred-deep-linking","tag-ios","tag-mobile-development","tag-pasteboard","tag-privacy","tag-user-experience"],"_links":{"self":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1289","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/comments?post=1289"}],"version-history":[{"count":3,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1289\/revisions"}],"predecessor-version":[{"id":2579,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1289\/revisions\/2579"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media\/1288"}],"wp:attachment":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media?parent=1289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/categories?post=1289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/tags?post=1289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}