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
| Platform | Content | URL |
|---|---|---|
| Web | Article #123 | https://example.com/article/123 |
| iOS App | Article #123 | https://example.com/article/123 |
| Android App | Article #123 | https://example.com/article/123 |
When all platforms use the same URL, your reports show total audience regardless of how users access your content.
Implementation
Option 1: Use Web URLs (Recommended)
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()
}
}
}
What the Link Tells Us
handleOpenURL() reads two things from the link, and only from the link:
- the campaign — its
utm_source,utm_medium,utm_campaign,utm_termandutm_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.