URLs & Deeplinks

Unify your analytics across web and mobile apps by using consistent URLs.

Cross-Platform URL Strategy

Alke Analytics allows you to reconcile audiences across all platforms (web, iOS, Android) by using the same URLs for the same content. This enables unified reporting where a single article or video shows combined metrics from all sources.

The Goal

PlatformContentURL
WebArticle #123https://example.com/article/123
iOS AppArticle #123https://example.com/article/123
Android AppArticle #123https://example.com/article/123

When all platforms use the same URL, your reports show total audience regardless of how users access your content.

Implementation

If your app supports Universal Links (iOS) or App Links (Android), use the actual web URL:

// Use the same URL as your website
AlkeAnalytics.pushPageView(
    url: "https://example.com/article/123",
    title: "Article Title"
)

// From a Universal Link
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    guard let url = userActivity.webpageURL else { return }

    // Hand the link over first: a url carrying utm_* opens a session and
    // attributes the arrival. Without this call there is no attribution at all.
    AlkeAnalytics.handleOpenURL(url)

    AlkeAnalytics.pushNavigation()
    AlkeAnalytics.pushPageView(
        url: url.absoluteString,
        title: pageTitle
    )
}

Option 2: Build Matching URLs

If you don’t have the web URL available, construct it to match your website structure:

// Build a URL that matches your web structure
let baseURL = "https://example.com"

// Article
AlkeAnalytics.pushPageView(
    url: "\(baseURL)/article/\(article.id)",
    title: article.title
)

// Category
AlkeAnalytics.pushPageView(
    url: "\(baseURL)/category/\(category.slug)",
    title: category.name
)

// Video
AlkeAnalytics.pushPageView(
    url: "\(baseURL)/video/\(video.id)",
    title: video.title
)

Option 3: App-Only Screens

For screens that don’t exist on web (settings, onboarding, etc.), use a consistent scheme:

// App-only screens
AlkeAnalytics.pushPageView(
    url: "app://settings",
    title: "Settings"
)

AlkeAnalytics.pushPageView(
    url: "app://onboarding/step-2",
    title: "Onboarding - Step 2"
)

Lifecycle Integration

Track pageviews when screens appear:

struct ArticleView: View {
    let article: Article

    var body: some View {
        ScrollView {
            // Content...
        }
        .onAppear {
            AlkeAnalytics.pushPageView(
                url: "https://example.com/article/\(article.id)",
                title: article.title
            )
        }
        .onDisappear {
            AlkeAnalytics.flush()
        }
    }
}

handleOpenURL() reads two things from the link, and only from the link:

  • the campaign — its utm_source, utm_medium, utm_campaign, utm_term and utm_content, carried by every report of the session the arrival opens;
  • the traffic source that campaign resolves to — one of eleven values, derived, never set by hand. See Traffic source for the list and for what an application can and cannot report.

A link carrying neither a utm_* nor a click identifier (gclid, msclkid, fbclid) declares no arrival: handleOpenURL() returns false and leaves the current session alone. Hand it every opening link anyway — deciding which ones are campaigns is its job, not yours.

URL Consistency
Document your URL mapping between web and mobile to ensure all teams use the same patterns. This is key to accurate cross-platform reporting.