Skip to content

feat(get-app): tag App Store links for App Analytics campaigns - #6958

Merged
nimrodkra merged 2 commits into
mainfrom
feat/app-store-campaign-links
Oct 19, 2026
Merged

nimrodkra merged 2 commits into
mainfrom
feat/app-store-campaign-links

Conversation

@nimrodkra

@nimrodkra nimrodkra commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Changes

  • App Store campaign tags: every App Store link on the webapp now carries Apple's campaign parameters: pt (our App Store Connect provider ID, 125432506) plus a ct surface tag. App Store Connect → App Analytics → Acquisition → Campaigns can then report impressions, downloads and conversion per surface. Today store taps carry only utm_source, which Apple ignores, so they all land in one undivided "Web Referrer" bucket.
    • GetAppButton (desktop popover) links to the App Store with ct=webapp_get_app_button.
    • The mobile header, footer and sheet "Open app" CTAs and the landing install card use the r.daily.dev/get smart link. It forwards its whole query string to the store, so pt and ct=webapp_<utm_source> reach the App Store. utm_source stays for our redirector logs, and Google Play ignores the Apple params. Verified live: r.daily.dev/get?utm_source=mobile_header&ct=…&pt=… ends at apps.apple.com/…?utm_source=mobile_header&ct=…&pt=….
    • New helper: features/getApp/appStoreLinks.ts (with spec). It caps ct at Apple's 40-character limit.
  • Smart App Banner app-argument: the banner now passes the page's canonical URL (https://daily.dev/...). Readers who have the app and tap Open land on the same post instead of the app's home. The iOS app already loads https URLs it receives through scene(_:openURLContexts:), and daily.dev is its primary origin.
  • Not changed: the two static QR codes (header popover and landing card). Longer URLs would make them denser around the logo knockout. As the note in getAppQr.svg says, their store attribution belongs on the redirector (api.daily.dev/get). A follow-up could add pt there and map utm_source → ct server-side, which would also cover emails and QR scans.

Context: the daily.dev iOS ASO plan, where web is about 30% of iOS first-time downloads and the plan relies on owned-channel download bursts we need to measure per surface. The marketing site (main-site) got the same pt in dailydotdev/recruiter-landing#601.

Events

No new tracking events. Existing download app events are unchanged.

Experiment

No.

Manual Testing

  • NODE_ENV=test jest src/features/getApp src/features/onboarding/components/signupHero in shared: 9 suites, 55 tests pass
  • pnpm --filter webapp test: 86 suites, 642 tests pass
  • pnpm --filter webapp typecheck: clean; scripts/typecheck-strict-changed.js origin/main: passes
  • ESLint is clean on the changed files
  • Not tested on a device: the Smart App Banner "Open" with app-argument should be checked on an iPhone with the app installed after deploy

🤖 Generated with Claude Code

Preview domain

https://feat-app-store-campaign-links.preview.app.daily.dev

Every App Store link on the webapp now carries Apple's campaign
parameters (pt, our App Store Connect provider ID, and a ct surface tag),
so App Store Connect > App Analytics > Campaigns can report impressions,
downloads and conversion per surface. Before this, store taps only
carried utm_source, which Apple ignores, so they all landed in one
undivided Web Referrer bucket.

- GetAppButton links straight to the App Store with ct=webapp_get_app_button.
- The mobile header, footer and sheet CTAs and the landing install card go
  through the r.daily.dev/get smart link, which forwards its whole query
  string to the store, so pt and ct ride along (ct=webapp_<utm_source>).
  utm_source stays for our own redirector logs.
- The static QR codes are unchanged: longer URLs would make them denser
  around the logo knockout, so their store attribution belongs on the
  redirector (api.daily.dev/get).

The Smart App Banner now passes app-argument with the page's canonical
URL. Readers who already have the app and tap Open land on the same page
instead of the app's home. The iOS app already loads https URLs it
receives through openURLContexts, on the same daily.dev origin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
daily-webapp Ready Ready Preview Oct 19, 2026 3:09pm UTC
storybook Ready Ready Preview Oct 19, 2026 3:09pm UTC

Request Review

@idoshamun idoshamun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Store links pick up pt/ct, and tracking events stay the same. The only change users see is the Smart App Banner app-argument, which opens the current page in the app. The iOS SceneDelegate loads incoming https URLs on both cold and warm start. Two notes, neither blocking: please check banner Open on an iPhone with the app installed after deploy. And on /search, the canonical query isn't encoded, so a comma in the search text would cut app-argument short.

Reviewed by AI.
Approved through AI review.

@nimrodkra
nimrodkra merged commit 8cedb74 into main Oct 19, 2026
12 checks passed
@nimrodkra
nimrodkra deleted the feat/app-store-campaign-links branch October 19, 2026 15:14

This branch was successfully deployed

2 active deployments
Preview – daily-webapp — 39b3715d Deployed Oct 19, 2026 by vercel[bot]
Preview – storybook — 39b3715d Deployed Oct 19, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants