Deep linking khi seeding traffic vào app: setup + measure 1 ngày xong
Tôi sẽ kể chuyện thật. Tháng 2/2025, tôi launch 1 app couple. Spend 8 triệu cho 5 KOC TikTok seeding. Mỗi KOC gắn link bio trỏ về App Store.
Kết quả: TikTok analytics báo 47,000 lượt click. App Store Connect báo 3,200 install. Conversion rate 6.8% — nghe có vẻ ổn.
Nhưng vấn đề thật bắt đầu sau install: 0% user vào đúng landing screen của campaign. Mỗi user vào app đều thấy onboarding mặc định — không có context "bạn đến từ KOC X", không có promo code auto-fill, không có direct route đến feature đang trend.
Kết quả 30 ngày sau: D7 retention chỉ 8% (vs benchmark 15-20%). Lý do? User vào app, không hiểu app này có gì khác KOC nói, churn ngay tuần đầu.
Đây là lý do deep link quan trọng. Bài này tôi sẽ giải thích deep link, universal link, app link, deferred deep link — và quan trọng nhất: setup hôm nay, đo conversion ngày mai.
Deep link là gì — định nghĩa thực dụng
Quên khái niệm tech document đi. Cho indie dev Việt 2026, deep link = link đưa user vào đúng màn hình trong app, kèm theo context từ campaign.
Ví dụ:
- Link bình thường:
https://myapp.com→ mở browser, end of story - Deep link (app đã cài):
https://myapp.com/promo/koc-mai→ mở app, vào màn hình promo, hiện code KOC Mai - Deferred deep link (app chưa cài): cùng link → App Store → user install → mở app → vẫn nhớ context KOC Mai → vào đúng màn hình promo
Cái cuối cùng (deferred) là chỗ 90% indie Việt fail.
3 loại deep link — phân biệt cho đúng
1. Custom URL scheme — kiểu cũ, đừng dùng nữa
myapp://promo/koc-mai
Vấn đề:
- Không work nếu app chưa cài (user thấy error)
- Không work khi click từ Safari/Chrome (security)
- Không share được qua iMessage/Zalo
- Bị Apple/Google deprecate dần
Bỏ qua. Không dùng năm 2026.
2. Universal Link (iOS) + App Link (Android)
https://myapp.com/promo/koc-mai
Đây là standard năm 2026. Dùng HTTPS URL thật:
- App đã cài → mở thẳng app
- App chưa cài → mở web (hoặc redirect App Store)
- Share được qua mọi channel
- SEO friendly
- Apple/Google đều support official
Đây là cái bạn nên setup.
3. Deferred Deep Link
Là universal/app link PLUS khả năng nhớ context khi user phải install app trước. Implement qua MMP (Branch, Adjust, AppsFlyer).
- User click link
https://myapp.com/promo/koc-mai - App chưa cài → vào App Store
- User install + mở app
- App đọc Branch SDK → biết user đến từ link
koc-mai - Auto navigate user vào promo screen + fill code
Đây là magic. Đây là cái KOC seeding cần.
Setup Universal Link cho iOS — 30 phút
Bước 1: Tạo Associated Domain
Ở Apple Developer portal:
- Vào Identifiers → chọn App ID
- Bật Associated Domains capability
- Save
Trong Xcode (hoặc Flutter ios/Runner):
- Signing & Capabilities → + Capability → Associated Domains
- Thêm:
applinks:myapp.comvàapplinks:www.myapp.com
Bước 2: Upload Apple App Site Association (AASA) file
Tạo file apple-app-site-association (KHÔNG có extension) tại https://myapp.com/.well-known/apple-app-site-association:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.yourcompany.myapp",
"paths": [
"/promo/*",
"/share/*",
"/invite/*",
"/post/*"
]
}
]
}
}
Lưu ý quan trọng:
- File phải serve qua HTTPS
- Content-Type phải là
application/json - Không redirect — Apple cấm
- KHÔNG đặt extension
.json
Laravel route:
// routes/web.php
Route::get('/.well-known/apple-app-site-association', function () {
return response()->json([
'applinks' => [
'apps' => [],
'details' => [[
'appID' => env('APPLE_TEAM_ID') . '.com.yourcompany.myapp',
'paths' => ['/promo/*', '/share/*', '/invite/*', '/post/*'],
]],
],
])->header('Content-Type', 'application/json');
});
Bước 3: Test
Dùng Apple's validator: https://search.developer.apple.com/appsearch-validation-tool
Nhập URL https://myapp.com/promo/test123 → kiểm tra xem AASA file có valid không.
Setup App Link cho Android — 20 phút
Bước 1: Thêm intent filter vào AndroidManifest.xml
<activity android:name=".MainActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"
android:host="myapp.com"
android:pathPrefix="/promo" />
<data android:scheme="https"
android:host="myapp.com"
android:pathPrefix="/share" />
</intent-filter>
</activity>
android:autoVerify="true" là magic ingredient — buộc Android verify domain ownership.
Bước 2: Upload assetlinks.json
Tạo file tại https://myapp.com/.well-known/assetlinks.json:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.yourcompany.myapp",
"sha256_cert_fingerprints": [
"AB:CD:EF:..."
]
}
}]
Lấy SHA-256 fingerprint từ keystore của bạn:
keytool -list -v -keystore ~/upload-keystore.jks -alias upload
Với Google Play App Signing (recommended 2026), thêm fingerprint từ Play Console → Setup → App Integrity.
Bước 3: Verify
Dùng Google Digital Asset Links tester: https://developers.google.com/digital-asset-links/tools/generator
Hoặc test direct:
adb shell pm verify-app-links --re-verify com.yourcompany.myapp
adb shell pm get-app-links com.yourcompany.myapp
Output phải có verified (không phải legacy_failure).
Setup Branch (Deferred Deep Link) — 1 giờ
Với universal/app link basic, bạn handle khi app đã cài. Để handle khi app chưa cài + giữ context → cần Branch (hoặc Adjust, AppsFlyer).
Tôi recommend Branch cho indie Việt vì:
- Free tier 10K MAU
- Setup nhanh nhất (1 giờ)
- Dashboard analytics tốt
- Support deferred deep link out-of-box
Bước 1: Tạo Branch account + app
- Đăng ký https://branch.io (free)
- Add new app → Configure iOS + Android
- Set Branch link domain (vd:
myapp.app.link)
Bước 2: Add Branch SDK
Flutter:
dependencies:
flutter_branch_sdk: ^8.0.0
React Native:
npm install react-native-branch
Native iOS/Android: theo doc Branch.
Bước 3: Initialize Branch trong app
Flutter ví dụ:
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
_initBranch();
}
void _initBranch() {
FlutterBranchSdk.initSession().listen((data) {
if (data.containsKey('+clicked_branch_link') &&
data['+clicked_branch_link'] == true) {
// User đến từ Branch link
final source = data['source'] ?? 'unknown';
final promoCode = data['promo_code'];
final targetScreen = data['target_screen'];
_navigateWithContext(targetScreen, source, promoCode);
}
});
}
}
Bước 4: Tạo deep link cho campaign
Qua Branch dashboard hoặc API:
curl -X POST https://api2.branch.io/v1/url \
-H 'Content-Type: application/json' \
-d '{
"branch_key": "key_live_xxx",
"channel": "tiktok",
"feature": "koc_seeding",
"campaign": "launch_couple_app_q1_2026",
"data": {
"source": "koc_mai",
"promo_code": "MAI20",
"target_screen": "promo_screen",
"$desktop_url": "https://myapp.com",
"$ios_url": "https://apps.apple.com/app/idXXX",
"$android_url": "https://play.google.com/store/apps/details?id=XXX"
}
}'
Response: { "url": "https://myapp.app.link/abc123" }
Link này gửi cho KOC → KOC put trong bio TikTok.
Đo lường conversion với deep link — dashboard cần check
Mỗi ngày sau khi KOC seeding, check 3 dashboard:
Branch dashboard
Key metrics:
| Metric | Ý nghĩa | Good benchmark |
|---|---|---|
| Link clicks | Tổng click vào Branch link | KOC reach × 2-5% |
| Install attribution | Install có Branch attribution | 60-80% click → install |
| Deferred deep link CTR | User vào đúng screen sau install | > 70% |
| Re-engagement | User click lại link khi đã có app | 10-20% |
Firebase Analytics
Custom events bạn nên track:
deep_link_received— app nhận deep linkdeep_link_navigated— user thực sự thấy target screenpromo_code_applied— promo từ deep link được applysignup_from_deeplink— signup happen sau khi đi qua deep link
Custom backend tracking
Đây là chỗ tôi recommend mạnh: log event ở backend của bạn ngoài Branch:
// Khi app gọi API signup
class SignupController extends Controller {
public function store(SignupRequest $request) {
$user = $this->authService->signup($request->validated());
// Log attribution
if ($request->has('branch_source')) {
$user->attribution()->create([
'channel' => $request->input('branch_source'),
'campaign' => $request->input('branch_campaign'),
'promo_code' => $request->input('branch_promo'),
]);
}
return new UserResource($user);
}
}
Bằng cách này, bạn có first-party attribution data không phụ thuộc bất kỳ 3rd party — important post-iOS 17 ATT.
Common pitfalls — đã ăn đủ rồi
Pitfall 1: AASA file bị cache nặng
Apple cache file AASA trong vài ngày. Nếu bạn deploy sai → fix → vẫn không work → đợi 7 ngày hoặc:
- Xóa app khỏi device
- Restart device
- Reinstall app từ App Store (không phải Xcode)
- Test lại
Pitfall 2: App Link không verify trên Android
Sau khi deploy assetlinks.json, app build và install qua Play Store. App build local (debug) không verify App Link → click link vẫn ra browser thay vì app.
Để test debug build, dùng:
adb shell am start -a android.intent.action.VIEW \
-d "https://myapp.com/promo/test123" com.yourcompany.myapp
Pitfall 3: Branch + Universal Link xung đột
Nếu setup cả Branch domain (myapp.app.link) + Universal Link domain (myapp.com) cùng lúc:
- Link Branch (
myapp.app.link/abc) → Branch SDK handle - Link own domain (
myapp.com/promo/x) → Universal Link handle, Branch không thấy
Solution: route own domain qua Branch bằng cách dùng custom domain trong Branch:
- Branch dashboard → Configuration → Link domains
- Add
app.myapp.com(subdomain riêng) - Update CNAME DNS record
- Mọi link
app.myapp.com/x→ Branch attribute myapp.com/x(main website) → web bình thường
Pitfall 4: Deep link không work khi share qua Zalo
Zalo wrap link qua redirect. Universal Link không work qua redirect.
Solution: dùng Branch link (myapp.app.link/abc) thay vì own domain — Branch xử lý redirect đúng.
Anecdote thật — app couple được fix sau deep link
Quay lại app couple đầu bài. Sau khi tôi setup deep link đầy đủ + redo campaign với cùng 5 KOC:
Trước (no deep link):
- 5 KOC × 8 triệu = 40 triệu total
- 47,000 click → 3,200 install (6.8% CTR)
- D7 retention: 8%
- 30-day revenue: 5.2 triệu
- ROI: -87%
Sau (có deep link + deferred):
- 5 KOC khác × 8 triệu = 40 triệu total
- 52,000 click → 3,800 install (7.3% CTR — slight boost)
- D7 retention: 19% (gấp 2.4 lần)
- 30-day revenue: 22 triệu
- ROI: -45%
Vẫn lỗ campaign — nhưng giảm lỗ 50%. Và quan trọng nhất: user retention healthier → LTV cao hơn → break-even ở month 4 thay vì "không bao giờ".
Lý do duy nhất khác: deep link đem user vào đúng promo screen với code auto-fill. User thấy KOC nói có code → vào app code đã có sẵn → trust tăng → retain.
Setup checklist 1 ngày — copy paste mà làm
Sáng (3-4h)
- Tạo Branch account free tier
- Configure iOS + Android trong Branch dashboard
- Setup Associated Domain (iOS) + Intent Filter (Android)
- Deploy AASA file lên
myapp.com/.well-known/ - Deploy assetlinks.json lên
myapp.com/.well-known/
Chiều (3-4h)
- Add Branch SDK vào app
- Code
_initBranch+ navigation handler - Code event tracking cho deep link
- Setup backend logging attribution
Tối (1-2h)
- Tạo 3-5 test link cho campaign sắp tới
- Test full funnel: click link (app chưa cài) → install → mở app → check landing screen + context
- Verify event xuất hiện trên Branch dashboard + Firebase + backend
Kết hợp deep link với các growth channel khác
Deep link không phải kênh đem install — nó là multiplier cho mọi channel. Khi bạn implement:
- KOC seeding: conversion tăng 30-60%
- Email campaign: CTR tăng 2-3x (vì user vào đúng screen)
- Push notification: re-engagement 5x
- Referral built-in: viral coefficient tăng 0.3-0.8 điểm
Tôi đã viết riêng 10 growth hack startup early-stage Việt Nam 2026 — trong đó deep link là foundation cho ít nhất 4 hack.
Tổng kết
Deep linking không sexy. Không một blog post nào về "How I grew my app to 1M users" nói về deep link. Nhưng nó là sự khác biệt giữa:
- 5000 click → 100 install retain → 1 paying user
- 5000 click → 350 install retain → 50 paying user
10x revenue chỉ vì user vào đúng màn hình trong app.
1 ngày setup. Lãi cả đời app.
Seeding traffic chất + measure đúng = winning combo
Deep link giúp bạn đo seeding traffic. Nhưng bạn cần traffic chất đầu vào trước. KOC seeding thật, beta tester thật, install thật từ user Việt — không phải bot.
Đây là chỗ GoSeedUp đóng vai trò:
- KOC review app: micro-influencer Việt thật, content có TikTok bio link dẫn về deep link của bạn — measure 100% được conversion
- Seeding install: 100-500 install thật, vào qua deep link → backend log attribution full
- Closed Testing job: 12-20 beta tester real device — kiểm tra deep link work trên thiết bị khác nhau trước khi launch ads
Tôi đã dùng cho cả 4 app gần nhất. KOC + deep link là combo thắng. Đăng job lên GoSeedUp hôm nay, deep link work ngày mai, conversion measure được tuần sau.