Skip to content
Tolinku
Tolinku
Sign In Start Free
Deep Linking · · 5 min read

Deep Linking in the Post-Cookie World

By Tolinku Staff
|
Tolinku deferred deep linking dashboard screenshot for deep linking blog posts

Third-party cookies are disappearing. Safari blocked them years ago. Firefox followed. Chrome is phasing them out through the Privacy Sandbox. For deep linking, this matters because many deferred deep linking and attribution systems relied on third-party cookies to match a web click to an app install.

The core deep linking functionality (opening the right content in the right app) is completely unaffected. Universal Links and App Links do not use cookies. What changes is the attribution and tracking layer that sits on top of deep links. This guide covers how to adapt. For privacy changes broadly, see privacy changes and their impact on deep linking. For deferred linking without fingerprinting, see deferred deep linking without fingerprinting.

What Third-Party Cookies Did for Deep Linking

The Old Model

Before cookie restrictions, a typical deferred deep linking flow looked like this:

1. User clicks deep link on Website A
2. Deep link service drops a third-party cookie (on its own domain)
3. User goes to the app store, installs the app
4. App opens, SDK checks for the cookie (via a web view or redirect)
5. Cookie matches → user is routed to the original content

The third-party cookie was the matching mechanism. It connected step 1 (web click) to step 5 (app open) across different contexts.

Why This Broke

Third-party cookies are blocked because they enable cross-site tracking. A cookie from tracking.example.com set on Site A could be read when the user visits Site B, creating a browsing profile across sites.

Deep link services used this same mechanism for legitimate purposes (matching a click to an install), but browsers do not distinguish between "good" and "bad" third-party cookies. All are blocked.

First-Party Data Strategies

URL Parameter Passing

The simplest post-cookie approach: carry attribution data in the URL itself.

Web page click → https://links.yourapp.com/products/shoes?click_id=abc123&source=blog
  → App store (referrer carries parameters on Android)
    → App opens → reads click_id from referrer → looks up click context server-side

No cookies needed. The attribution data travels with the link.

// Server: generate a click with server-side context
app.get('/link/:slug', async (req, res) => {
  const clickId = crypto.randomUUID();

  // Store click context server-side
  await clickStore.save({
    clickId,
    slug: req.params.slug,
    source: req.query.utm_source,
    campaign: req.query.utm_campaign,
    ip: req.ip,
    userAgent: req.headers['user-agent'],
    timestamp: Date.now()
  });

  // Build app store URL with click ID
  const storeUrl = buildStoreUrl({
    referrer: `click_id=${clickId}&utm_source=${req.query.utm_source}`
  });

  res.redirect(302, storeUrl);
});

First-Party Cookies

First-party cookies (set by your own domain) still work everywhere. If your deep link URL is on your own domain, you can use first-party cookies:

// Set a first-party cookie on your domain
app.get('/link/:slug', (req, res) => {
  const clickId = crypto.randomUUID();

  res.cookie('tolk_click', clickId, {
    maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
    httpOnly: true,
    secure: true,
    sameSite: 'lax',
    domain: '.yourapp.com' // your domain
  });

  // Continue with the redirect flow
  redirectToAppOrStore(req, res, clickId);
});

If the user later visits your website (on the same domain) after installing the app, the first-party cookie matches the click:

// On your website, after user installs and visits
app.get('/welcome-back', (req, res) => {
  const clickId = req.cookies.tolk_click;
  if (clickId) {
    const originalClick = await clickStore.get(clickId);
    // Match: this user came from our deep link campaign
  }
});

Server-Side Click Matching

Move the matching logic from the browser (cookies) to the server:

// Server-side click matching
class ClickMatcher {
  async matchInstallToClick(installData) {
    const { ip, userAgent, timestamp, referrer } = installData;

    // 1. Try exact match via referrer (Android Install Referrer)
    if (referrer) {
      const clickId = new URLSearchParams(referrer).get('click_id');
      if (clickId) {
        return await this.getClick(clickId);
      }
    }

    // 2. Try probabilistic match (within strict time window)
    const recentClicks = await this.getRecentClicks({
      ip,
      userAgent,
      maxAge: 60 * 60 * 1000 // 1 hour window
    });

    if (recentClicks.length === 1) {
      return recentClicks[0]; // High confidence single match
    }

    // 3. No match found
    return null;
  }
}

Platform-Specific Solutions

Android: Install Referrer API

Google Play's Install Referrer API is the most reliable post-cookie attribution method on Android. It passes referral parameters through the install:

val client = InstallReferrerClient.newBuilder(context).build()
client.startConnection(object : InstallReferrerStateListener {
    override fun onInstallReferrerSetupFinished(responseCode: Int) {
        if (responseCode == InstallReferrerResponse.OK) {
            val details = client.installReferrer
            val referrer = details.installReferrer
            // referrer = "click_id=abc123&utm_source=blog&utm_campaign=summer"

            val params = Uri.parse("?$referrer")
            val clickId = params.getQueryParameter("click_id")
            val source = params.getQueryParameter("utm_source")

            // Fetch the original click context
            fetchClickContext(clickId) { context ->
                navigateToContent(context.slug)
            }
        }
        client.endConnection()
    }

    override fun onInstallReferrerServiceDisconnected() {}
})

This is first-party Google data, privacy-compliant, and works without cookies.

iOS: Pasteboard and SKAdNetwork

iOS has no equivalent to the Install Referrer API. Alternatives:

Pasteboard (clipboard): Copy a token to the clipboard on web click, read it in the app. Since iOS 16, users see a permission prompt for clipboard access, reducing reliability.

SKAdNetwork: Provides aggregate campaign attribution (which campaign drove installs) but not user-level deep link matching. It does not help with deferred deep linking to specific content.

App Store overlay: When Apple's Smart App Banner is used, the app-argument parameter can carry a URL:

<meta name="apple-itunes-app" content="app-id=YOUR_ID, app-argument=https://yourapp.com/products/shoes">

If the user installs via the Smart App Banner, the app receives the app-argument URL on launch.

Attribution Models in the Post-Cookie World

Deterministic vs. Probabilistic

Method Type Accuracy Privacy
Install Referrer (Android) Deterministic ~100% First-party
First-party cookies Deterministic ~95% First-party
User login matching Deterministic ~100% First-party
Server-side IP+UA Probabilistic ~60-80% Gray area
Fingerprinting Probabilistic ~70-85% Restricted

Self-Reported Attribution

Ask users directly how they found your app:

// On first app launch
class OnboardingActivity : AppCompatActivity() {
    fun showAttributionSurvey() {
        val options = listOf(
            "Search (Google, Bing)",
            "Social media",
            "Friend or colleague",
            "Blog post or article",
            "QR code",
            "Advertisement",
            "Other"
        )
        showSurveyDialog("How did you hear about us?", options) { selected ->
            analytics.trackSelfReportedAttribution(selected)
        }
    }
}

This is privacy-friendly and provides qualitative data that automated attribution misses.

Architecture

Web click
  → Server generates click ID, stores context
    → URL carries click ID to app store
      → Android: Install Referrer passes click ID
      → iOS: Smart App Banner app-argument carries URL
        → App opens, reads click ID
          → Server looks up click context
            → App navigates to original content

No cookies at any step. The attribution data flows through URL parameters and platform APIs.

Implementation Checklist

  1. Generate unique click IDs server-side for every deep link click.
  2. Store click context (source, campaign, content, timestamp) server-side.
  3. Pass click ID through the install flow via URL parameters.
  4. On Android, read the Install Referrer to get the click ID.
  5. On iOS, use Smart App Banner app-argument or first-party cookies on your domain.
  6. On app launch, fetch click context from your server using the click ID.
  7. Navigate to the original content.

Tolinku Post-Cookie Attribution

Tolinku uses first-party data for deep link attribution. Deep links use your own custom domain, which means first-party cookies are available. Click context is stored server-side, and attribution data flows through URL parameters and platform APIs (Install Referrer on Android, Smart App Banner on iOS).

Configure your attribution in the Tolinku dashboard. For the broader privacy strategy, see privacy changes and their impact on deep linking.

Get deep linking tips in your inbox

One email per week. No spam.

Ready to add deep linking to your app?

Set up Universal Links, App Links, deferred deep linking, and analytics in minutes. Free to start.